ZQuest Classic Coverage Report


Directory: src/
File: src/zc/maps.cpp
Date: 2025-10-22 06:47:12
Exec Total Coverage
Lines: 4199 5245 80.1%
Functions: 295 334 88.3%
Branches: 3250 5314 61.2%

Line Branch Exec Source
1 #include "base/combo.h"
2 #include "base/handles.h"
3 #include "base/util.h"
4 #include "base/zdefs.h"
5 #include "base/general.h"
6 #include <cstring>
7 #include <assert.h>
8 #include <math.h>
9 #include <vector>
10 #include <deque>
11 #include <string>
12 #include <set>
13 #include <array>
14 #include <sstream>
15 using std::set;
16
17 #include "base/qrs.h"
18 #include "base/dmap.h"
19 #include "base/mapscr.h"
20 #include "base/misctypes.h"
21 #include "base/initdata.h"
22 #include "zc/maps.h"
23 #include "zc/zelda.h"
24 #include "zc/zc_ffc.h"
25 #include "tiles.h"
26 #include "sprite.h"
27 #include "gui/jwin.h"
28 #include "base/zsys.h"
29 #include "subscr.h"
30 #include "zc/zc_subscr.h"
31 #include "zc/hero.h"
32 #include "zc/guys.h"
33 #include "zc/ffscript.h"
34 #include "drawing.h"
35 #include "zc/combos.h"
36 #include "zc/replay.h"
37 #include "slopes.h"
38 #include "particles.h"
39 #include <fmt/format.h>
40 #include "zc/render.h"
41 #include "iter.h"
42 #include <ranges>
43
44 // All the temporary screens (and their layers) for the currently loaded map.
45 static mapscr* temporary_screens[136*7];
46 // Set by load_region.
47 static bool screen_in_current_region[136];
48 424 static rpos_handle_t current_region_rpos_handles[136*7];
49 static bool current_region_rpos_handles_dirty;
50 static int current_region_screen_count;
51 static std::pair<const rpos_handle_t*, int> current_region_rpos_handles_scr[136];
52
53 viewport_t viewport;
54 static int viewport_sprite_uid;
55 ViewportMode viewport_mode;
56 int world_w, world_h;
57 int region_scr_dx, region_scr_dy;
58 int region_scr_count;
59 rpos_t region_max_rpos;
60 int region_num_rpos;
61 region_t cur_region, scrolling_region;
62
63 424 maze_state_t maze_state;
64 int scrolling_maze_last_solved_screen;
65
66 605 void maps_init_game_vars()
67 {
68 605 viewport = {};
69 605 viewport_mode = ViewportMode::CenterAndBound;
70 605 viewport_sprite_uid = 1;
71 605 currscr_for_passive_subscr = -1;
72 605 }
73
74 static region_ids_t current_region_ids;
75
76 // Returns true if the (map, screen) is inside a scrolling region.
77 15144963 static bool is_in_scrolling_region(int map, int screen)
78 {
79 15144963 return get_region_id(map, screen) != 0;
80 }
81
82 bool is_in_screenscrolling_region(int screen)
83 {
84 if (!screenscrolling) return false;
85
86 int x = screen % 16;
87 int y = screen / 16;
88 return
89 scrolling_region.origin_screen_x >= x && scrolling_region.origin_screen_x < x + scrolling_region.screen_width &&
90 scrolling_region.origin_screen_y >= y && scrolling_region.origin_screen_y < y + scrolling_region.screen_height;
91 }
92
93 9001770005 bool is_in_scrolling_region()
94 {
95 9001770005 return cur_region.screen_count > 1;
96 }
97
98 2232 static bool is_same_region_id(int region_origin_scr, int map, int scr)
99 {
100
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 1460 times.
2232 if (!is_in_scrolling_region(map, scr)) return false;
101 1460 int region_id = get_region_id(map, region_origin_scr);
102
1/2
✓ Branch 0 taken 1460 times.
✗ Branch 1 not taken.
1460 return region_id && region_id == get_region_id(map, scr);
103 2232 }
104
105 251051835 bool is_in_current_region(int map, int screen)
106 {
107
2/2
✓ Branch 0 taken 1598 times.
✓ Branch 1 taken 251050237 times.
251051835 if (map != cur_map)
108 1598 return false;
109
110
3/4
✓ Branch 0 taken 251050237 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 251038024 times.
✓ Branch 3 taken 12213 times.
251050237 if (screen >= 0 && screen < 128)
111 251038024 return screen_in_current_region[screen];
112
113 12213 return screen == cur_screen;
114 251051835 }
115
116 244716858 bool is_in_current_region(int screen)
117 {
118
5/6
✓ Branch 0 taken 243601240 times.
✓ Branch 1 taken 1115618 times.
✓ Branch 2 taken 1115618 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1115613 times.
244716858 return screen == cur_screen || (screen >= 0 && screen < 128 && screen_in_current_region[screen]);
119 }
120
121 30753304 bool is_in_current_region(mapscr* scr)
122 {
123
2/2
✓ Branch 0 taken 14690 times.
✓ Branch 1 taken 30738614 times.
30753304 return scr->map == cur_map && is_in_current_region(scr->screen);
124 }
125
126 63767766 bool is_extended_height_mode()
127 {
128
2/2
✓ Branch 0 taken 63568318 times.
✓ Branch 1 taken 199448 times.
63767766 return cur_region.screen_height > 1 && (DMaps[cur_dmap].flags & dmfEXTENDEDVIEWPORT);
129 }
130
131 // Returns 0 if this is not a scrolling region.
132 42483755 int get_region_id(int map, int screen)
133 {
134
2/2
✓ Branch 0 taken 401435 times.
✓ Branch 1 taken 42082320 times.
42483755 if (screen >= 128) return 0;
135
2/2
✓ Branch 0 taken 42081196 times.
✓ Branch 1 taken 1124 times.
42082320 if (map == cur_region.map) return current_region_ids[screen];
136
137 1124 return Regions[map].get_region_id(screen);
138 42483755 }
139
140 27276802 int get_current_region_id()
141 {
142 27276802 return get_region_id(cur_map, cur_screen);
143 }
144
145 67241 void calculate_region(int map, int screen, region_t& region, int& region_scr_dx, int& region_scr_dy)
146 {
147 67241 region.map = map;
148
149
2/2
✓ Branch 0 taken 66967 times.
✓ Branch 1 taken 274 times.
67241 if (!is_in_scrolling_region(map, screen))
150 {
151 66967 region.region_id = 0;
152 66967 region.origin_screen = screen;
153 66967 region.origin_screen_x = screen % 16;
154 66967 region.origin_screen_y = screen / 16;
155 66967 region.screen_width = 1;
156 66967 region.screen_height = 1;
157 66967 region.screen_count = 1;
158 66967 region.width = 256;
159 66967 region.height = 176;
160 66967 region_scr_dx = 0;
161 66967 region_scr_dy = 0;
162 66967 return;
163 }
164
165 274 int input_scr_x = screen % 16;
166 274 int input_scr_y = screen / 16;
167
168 // For the given screen, find the top-left corner of its region.
169 274 int origin_scr_x = input_scr_x;
170 274 int origin_scr_y = input_scr_y;
171 274 int origin_scr = screen;
172
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 372 times.
434 while (origin_scr_x > 0)
173 {
174
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 160 times.
372 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x - 1, origin_scr_y))) break;
175 160 origin_scr_x--;
176 }
177
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 414 times.
508 while (origin_scr_y > 0)
178 {
179
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 234 times.
414 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, origin_scr_y - 1))) break;
180 234 origin_scr_y--;
181 }
182 274 origin_scr = map_scr_xy_to_index(origin_scr_x, origin_scr_y);
183
184 // Now find the bottom-right corner.
185 274 int region_scr_right = origin_scr_x;
186
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 614 times.
642 while (region_scr_right < 15)
187 {
188
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 368 times.
614 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(region_scr_right + 1, origin_scr_y))) break;
189 368 region_scr_right++;
190 }
191 274 int region_scr_bottom = origin_scr_y;
192
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 832 times.
856 while (region_scr_bottom < 7)
193 {
194
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 582 times.
832 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, region_scr_bottom + 1))) break;
195 582 region_scr_bottom++;
196 }
197
198 274 region.region_id = get_region_id(map, origin_scr);
199 274 region.origin_screen = origin_scr;
200 274 region.origin_screen_x = origin_scr_x;
201 274 region.origin_screen_y = origin_scr_y;
202 274 region.screen_width = region_scr_right - origin_scr_x + 1;
203 274 region.screen_height = region_scr_bottom - origin_scr_y + 1;
204 274 region.screen_count = region.screen_width * region.screen_height;
205 274 region.width = 256 * region.screen_width;
206 274 region.height = 176 * region.screen_height;
207 274 region_scr_dx = input_scr_x - origin_scr_x;
208 274 region_scr_dy = input_scr_y - origin_scr_y;
209
210 DCHECK_RANGE_INCLUSIVE(region.screen_width, 0, 16);
211 DCHECK_RANGE_INCLUSIVE(region.screen_height, 0, 8);
212 67241 }
213
214 37527 void load_region(int dmap, int screen)
215 {
216 37527 clear_temporary_screens();
217
218 37527 int map = DMaps[dmap].map;
219 37527 current_region_ids = Regions[map].get_all_region_ids();
220
221 37527 calculate_region(map, screen, cur_region, region_scr_dx, region_scr_dy);
222 37527 cur_screen = cur_region.origin_screen;
223 37527 world_w = cur_region.width;
224 37527 world_h = cur_region.height;
225 37527 region_scr_count = cur_region.screen_count;
226 37527 region_max_rpos = (rpos_t)(cur_region.screen_count*176 - 1);
227 37527 region_num_rpos = cur_region.screen_count*176;
228 37527 scrolling_maze_last_solved_screen = 0;
229
230 37527 memset(screen_in_current_region, false, sizeof(screen_in_current_region));
231
2/2
✓ Branch 0 taken 37761 times.
✓ Branch 1 taken 37527 times.
75288 for (int x = 0; x < cur_region.screen_width; x++)
232 {
233
2/2
✓ Branch 0 taken 38771 times.
✓ Branch 1 taken 37761 times.
76532 for (int y = 0; y < cur_region.screen_height; y++)
234 {
235 38771 int screen = cur_screen + x + y*16;
236
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38771 times.
38771 if (screen < 136)
237 {
238 38771 screen_in_current_region[screen] = true;
239 38771 }
240 38771 }
241 37761 }
242
243 37527 mark_current_region_handles_dirty();
244 37527 }
245
246 37527 static void prepare_current_region_handles()
247 {
248 37527 current_region_rpos_handles_dirty = false;
249 37527 current_region_screen_count = 0;
250
2/2
✓ Branch 0 taken 37875 times.
✓ Branch 1 taken 37527 times.
75402 for (int y = 0; y < cur_region.screen_height; y++)
251 {
252
2/2
✓ Branch 0 taken 38771 times.
✓ Branch 1 taken 37875 times.
76646 for (int x = 0; x < cur_region.screen_width; x++)
253 {
254 38771 int screen = cur_screen + x + y*16;
255 38771 int index_start = current_region_screen_count;
256
2/2
✓ Branch 0 taken 38771 times.
✓ Branch 1 taken 271397 times.
310168 for (int layer = 0; layer <= 6; layer++)
257 {
258 271397 mapscr* scr = get_scr_layer(screen, layer);
259
2/2
✓ Branch 0 taken 95240 times.
✓ Branch 1 taken 176157 times.
271397 if (!scr->is_valid())
260 {
261
1/2
✓ Branch 0 taken 176157 times.
✗ Branch 1 not taken.
176157 if (layer == 0) break;
262 176157 continue;
263 }
264
265 95240 rpos_t base_rpos = POS_TO_RPOS(0, get_region_relative_dx(screen), get_region_relative_dy(screen));
266 95240 current_region_rpos_handles[current_region_screen_count] = {scr, screen, layer, base_rpos, 0};
267 95240 current_region_screen_count += 1;
268 95240 }
269
270 38771 int num_handles_for_scr = current_region_screen_count - index_start;
271 38771 current_region_rpos_handles_scr[screen] = {&current_region_rpos_handles[index_start], num_handles_for_scr};
272 38771 }
273 37875 }
274 37527 }
275
276 1814229549 std::tuple<const rpos_handle_t*, int> get_current_region_handles()
277 {
278 DCHECK(!current_region_rpos_handles_dirty);
279 1814229549 return {current_region_rpos_handles, current_region_screen_count};
280 }
281
282 11476970 std::tuple<const rpos_handle_t*, int> get_current_region_handles(mapscr* scr)
283 {
284 DCHECK(!current_region_rpos_handles_dirty);
285
2/4
✓ Branch 0 taken 11476970 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11476970 times.
11476970 if (scr == special_warp_return_scr || current_region_rpos_handles_dirty)
286 return {nullptr, 0};
287
288
2/2
✓ Branch 0 taken 65877 times.
✓ Branch 1 taken 11411093 times.
11476970 if (cur_screen >= 0x80)
289 {
290 DCHECK(scr == origin_scr);
291 65877 return {nullptr, 0};
292 }
293
294 DCHECK(is_in_current_region(scr));
295 11411093 return current_region_rpos_handles_scr[scr->screen];
296 11476970 }
297
298 37527 void mark_current_region_handles_dirty()
299 {
300 37527 current_region_rpos_handles_dirty = true;
301 37527 }
302
303 67997 void delete_temporary_screens(mapscr** screens)
304 {
305
2/2
✓ Branch 0 taken 64733144 times.
✓ Branch 1 taken 67997 times.
64801141 for (int i = 0; i < 136*7; i++)
306 {
307
2/2
✓ Branch 0 taken 267351 times.
✓ Branch 1 taken 64465793 times.
64733144 if (!screens[i])
308 64465793 continue;
309
310 267351 mapscr* scr = screens[i];
311 267351 int num_ffcs = scr->numFFC();
312
2/2
✓ Branch 0 taken 7621503 times.
✓ Branch 1 taken 267351 times.
7888854 for (int i = 0; i < num_ffcs; i++)
313 {
314 7621503 sprite* ffc = &scr->ffcs[i];
315
2/2
✓ Branch 0 taken 7617968 times.
✓ Branch 1 taken 3535 times.
7621503 if (ffc->uid)
316 3535 FFCore.release_sprite_owned_objects(ffc->uid);
317 7621503 }
318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 267351 times.
267351 delete scr;
319 267351 screens[i] = NULL;
320 267351 }
321 67997 }
322
323 38694 void clear_temporary_screens()
324 {
325 38694 delete_temporary_screens(temporary_screens);
326 38694 origin_scr = nullptr;
327 38694 hero_scr = nullptr;
328 38694 }
329
330 29307 std::vector<mapscr*> take_temporary_scrs()
331 {
332
1/2
✓ Branch 0 taken 29307 times.
✗ Branch 1 not taken.
29307 std::vector<mapscr*> screens(temporary_screens, temporary_screens + 136*7);
333
2/2
✓ Branch 0 taken 29307 times.
✓ Branch 1 taken 27900264 times.
27929571 for (int i = 0; i < 136*7; i++)
334 27900264 temporary_screens[i] = nullptr;
335
336 29307 return screens;
337
1/2
✓ Branch 0 taken 29307 times.
✗ Branch 1 not taken.
29307 }
338
339 15075850 void calculate_viewport(viewport_t& viewport, int dmap, int screen, int world_w, int world_h, int x, int y)
340 {
341 // TODO: In future, maybe add x/y centering offsets to zscript (Viewport->TargetXOffset/Viewport->TargetYOffset).
342
343
2/2
✓ Branch 0 taken 15029268 times.
✓ Branch 1 taken 46582 times.
15075850 bool extended_height_mode = (DMaps[dmap].flags & dmfEXTENDEDVIEWPORT) && world_h > 176;
344 15075850 viewport.w = 256;
345 15075850 viewport.h = 176 + (extended_height_mode ? 56 : 0);
346
347
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 15075490 times.
15075850 if (viewport_mode == ViewportMode::Script)
348 360 return;
349
350
2/2
✓ Branch 0 taken 46162 times.
✓ Branch 1 taken 15029328 times.
15075490 if (!is_in_scrolling_region(DMaps[dmap].map, screen))
351 {
352 15029328 viewport.x = 0;
353 15029328 viewport.y = 0;
354 15029328 }
355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46162 times.
46162 else if (viewport_mode == ViewportMode::CenterAndBound)
356 {
357 // Clamp the viewport to the edges of the region.
358
6/6
✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 37594 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 39374 times.
✓ Branch 4 taken 8568 times.
✓ Branch 5 taken 30806 times.
46162 viewport.x = CLAMP(0, world_w - viewport.w, x - viewport.w/2);
359
6/6
✓ Branch 0 taken 11856 times.
✓ Branch 1 taken 34306 times.
✓ Branch 2 taken 5650 times.
✓ Branch 3 taken 40512 times.
✓ Branch 4 taken 11856 times.
✓ Branch 5 taken 28656 times.
46162 viewport.y = CLAMP(0, world_h - viewport.h, y - viewport.h/2);
360 46162 }
361 else if (viewport_mode == ViewportMode::Center)
362 {
363 viewport.x = x - viewport.w/2;
364 viewport.y = y - viewport.h/2;
365 }
366 15075850 }
367
368 15075339 sprite* get_viewport_sprite()
369 {
370 15075339 sprite* spr = sprite::getByUID(viewport_sprite_uid);
371
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 15075333 times.
15075339 if (!spr)
372 {
373 6 viewport_sprite_uid = 1; // Hero uid.
374 6 spr = &Hero;
375 6 }
376
377 15075339 return spr;
378 }
379
380 6 void set_viewport_sprite(sprite* spr)
381 {
382 6 viewport_sprite_uid = spr->uid;
383 6 }
384
385 15046032 void update_viewport()
386 {
387 15046032 sprite* spr = get_viewport_sprite();
388 15046032 int x = spr->x + spr->txsz*16/2;
389 15046032 int y = spr->y + spr->tysz*16/2;
390 15046032 calculate_viewport(viewport, cur_dmap, cur_screen, world_w, world_h, x, y);
391 15046032 }
392
393 // TODO: should add a moveflag to sprites to configure the size of this rect (or effectively disable
394 // freezing if the rect returns is large enough). See:
395 // https://discord.com/channels/876899628556091432/1358483603700449581
396 // https://discord.com/channels/876899628556091432/1130384911983980554
397 //
398 89012224 viewport_t get_sprite_freeze_rect()
399 {
400 89012224 viewport_t freeze_rect = viewport;
401 89012224 int tile_buffer = 3;
402 89012224 freeze_rect.w += 16 * tile_buffer * 2;
403 89012224 freeze_rect.h += 16 * tile_buffer * 2;
404 89012224 freeze_rect.x -= 16 * tile_buffer;
405 89012224 freeze_rect.y -= 16 * tile_buffer;
406 89012224 return freeze_rect;
407 }
408
409 4722 mapscr* determine_hero_screen_from_coords()
410 {
411 4722 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
412 4722 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
413 4722 int dx = x / 256;
414 4722 int dy = y / 176;
415 4722 return get_scr(cur_screen + dx + dy * 16);
416 }
417
418 28218 bool edge_of_region(direction dir)
419 {
420
2/2
✓ Branch 0 taken 28138 times.
✓ Branch 1 taken 80 times.
28218 if (!is_in_scrolling_region()) return true;
421
422 80 int screen_x = Hero.current_screen % 16;
423 80 int screen_y = Hero.current_screen / 16;
424
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if (dir == up) screen_y -= 1;
425
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 10 times.
80 if (dir == down) screen_y += 1;
426
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 30 times.
80 if (dir == left) screen_x -= 1;
427
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 38 times.
80 if (dir == right) screen_x += 1;
428
4/8
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
80 if (screen_x < 0 || screen_x > 16 || screen_y < 0 || screen_y > 8) return true;
429 80 return !is_in_current_region(map_scr_xy_to_index(screen_x, screen_y));
430 28218 }
431
432 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
433 // Coordinates are clamped to the world bounds.
434 338056796 int get_screen_for_world_xy(int x, int y)
435 {
436
2/2
✓ Branch 0 taken 316917772 times.
✓ Branch 1 taken 21139024 times.
338056796 if (!is_in_scrolling_region())
437 316917772 return cur_screen;
438
439 21139024 int dx = std::clamp(x, 0, world_w - 1) / 256;
440 21139024 int dy = std::clamp(y, 0, world_h - 1) / 176;
441 21139024 int origin_screen_x = cur_screen % 16;
442 21139024 int origin_screen_y = cur_screen / 16;
443 21139024 int scr_x = origin_screen_x + dx;
444 21139024 int scr_y = origin_screen_y + dy;
445 21139024 return map_scr_xy_to_index(scr_x, scr_y);
446 338056796 }
447
448 31102071 int get_screen_for_rpos(rpos_t rpos)
449 {
450 31102071 int origin_screen_x = cur_screen % 16;
451 31102071 int origin_screen_y = cur_screen / 16;
452 31102071 int screen = static_cast<int32_t>(rpos) / 176;
453 31102071 int scr_x = origin_screen_x + screen%cur_region.screen_width;
454 31102071 int scr_y = origin_screen_y + screen/cur_region.screen_width;
455 31102071 return map_scr_xy_to_index(scr_x, scr_y);
456 }
457
458 837083482 rpos_handle_t get_rpos_handle(rpos_t rpos, int layer)
459 {
460 DCHECK_LAYER_ZERO_INDEX(layer);
461
2/2
✓ Branch 0 taken 806119374 times.
✓ Branch 1 taken 30964108 times.
837083482 if (!is_in_scrolling_region())
462 806119374 return {get_scr_layer(cur_screen, layer), cur_screen, layer, rpos, RPOS_TO_POS(rpos)};
463 30964108 int screen = get_screen_for_rpos(rpos);
464 30964108 mapscr* scr = get_scr_layer(screen, layer);
465 30964108 return {scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
466 837083482 }
467
468 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
469 // Coordinates are clamped to the world bounds.
470 3483909799 rpos_handle_t get_rpos_handle_for_world_xy(int x, int y, int layer)
471 {
472 3483909799 x = std::clamp(x, 0, world_w - 1);
473 3483909799 y = std::clamp(y, 0, world_h - 1);
474
475 DCHECK_LAYER_ZERO_INDEX(layer);
476
2/2
✓ Branch 0 taken 3457567321 times.
✓ Branch 1 taken 26342478 times.
3483909799 if (!is_in_scrolling_region())
477 {
478 3457567321 int pos = COMBOPOS(x, y);
479 3457567321 return {get_scr_layer(cur_screen, layer), cur_screen, layer, (rpos_t)pos, pos};
480 }
481 26342478 return get_rpos_handle(COMBOPOS_REGION(x, y), layer);
482 3483909799 }
483
484 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
485 1926 rpos_handle_t get_rpos_handle_for_screen(int screen, int layer, int pos)
486 {
487 DCHECK_LAYER_ZERO_INDEX(layer);
488 1926 return {get_scr_layer(screen, layer), screen, layer, POS_TO_RPOS(pos, screen), pos};
489 }
490
491 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
492 // Use this instead of the other `get_pos_handle_for_screen` if you already have a reference to the screen.
493 63140 rpos_handle_t get_rpos_handle_for_scr(mapscr* scr, int layer, int pos)
494 {
495 DCHECK_LAYER_ZERO_INDEX(layer);
496 63140 return {scr, scr->screen, layer, POS_TO_RPOS(pos, scr->screen), pos};
497 }
498
499 25567743 void change_rpos_handle_layer(rpos_handle_t& rpos_handle, int layer)
500 {
501 DCHECK_LAYER_ZERO_INDEX(layer);
502 25567743 rpos_handle.layer = layer;
503 25567743 rpos_handle.scr = get_scr_layer(rpos_handle.screen, layer);
504 25567743 }
505
506 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
507 // Coordinates are clamped to the world bounds.
508 86712 combined_handle_t get_combined_handle_for_world_xy(int x, int y, int layer)
509 {
510 DCHECK_LAYER_ZERO_INDEX(layer);
511
512 86712 x = std::clamp(x, 0, world_w - 1);
513 86712 y = std::clamp(y, 0, world_h - 1);
514
515 86712 auto maybe_ffc_handle = getFFCAt(x, y);
516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86712 times.
86712 if (maybe_ffc_handle)
517 return maybe_ffc_handle.value();
518
519 86712 auto rpos = COMBOPOS_REGION_B(x, y);
520
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86712 times.
86712 if (rpos == rpos_t::None)
521 return rpos_handle_t();
522 86712 return get_rpos_handle(rpos, layer);
523 86712 }
524
525 // These functions all return _temporary_ screens. Any modifications made to them (either by the engine
526 // directly or via zscript) only last until the next area is loaded (via loadscr).
527
528 // Returns the screen containing the (x, y) world position.
529 1554872063 mapscr* get_scr_for_world_xy(int x, int y)
530 {
531 // Quick path, but should work the same without.
532
2/2
✓ Branch 0 taken 1544432663 times.
✓ Branch 1 taken 10439400 times.
1554872063 if (!is_in_scrolling_region()) return origin_scr;
533 10439400 return get_scr(get_screen_for_world_xy(x, y));
534 1554872063 }
535
536 25989648 mapscr* get_scr_for_rpos(rpos_t rpos)
537 {
538 // Quick path, but should work the same without.
539
2/2
✓ Branch 0 taken 25851702 times.
✓ Branch 1 taken 137946 times.
25989648 if (!is_in_scrolling_region()) return origin_scr;
540 137946 return get_scr(get_screen_for_rpos(rpos));
541 25989648 }
542
543 17 mapscr* get_scr_for_rpos_layer(rpos_t rpos, int layer)
544 {
545 17 return get_scr_layer(get_screen_for_rpos(rpos), layer);
546 }
547
548 // Note: layer=0 is the base screen, 1 is the first layer, etc.
549 2135140074 mapscr* get_scr_for_world_xy_layer(int x, int y, int layer)
550 {
551 DCHECK_LAYER_ZERO_INDEX(layer);
552
2/2
✓ Branch 0 taken 2125094860 times.
✓ Branch 1 taken 10045214 times.
2135140074 if (!is_in_scrolling_region()) return get_scr_layer(cur_screen, layer);
553
2/2
✓ Branch 0 taken 708934 times.
✓ Branch 1 taken 9336280 times.
10045214 return layer == 0 ?
554 708934 get_scr_for_world_xy(x, y) :
555 9336280 get_scr_layer(get_screen_for_world_xy(x, y), layer);
556 2135140074 }
557
558 1856896134 int get_region_screen_offset(int screen)
559 {
560 1856896134 return get_region_relative_dx(screen) + get_region_relative_dy(screen) * cur_region.screen_width;
561 }
562
563 655240230 int get_screen_for_region_index_offset(int offset)
564 {
565 655240230 int scr_dx = offset % cur_region.screen_width;
566 655240230 int scr_dy = offset / cur_region.screen_width;
567 655240230 int screen = cur_screen + scr_dx + scr_dy*16;
568 655240230 return screen;
569 }
570
571 655056392 mapscr* get_scr_for_region_index_offset(int offset)
572 {
573 655056392 int screen = get_screen_for_region_index_offset(offset);
574 655056392 return get_scr(screen);
575 }
576
577 // The screen at (map, screen) must exist.
578 1540889822 mapscr* get_scr(int map, int screen)
579 {
580 1540889822 mapscr* scr = get_scr_maybe(map, screen);
581
1/2
✓ Branch 0 taken 1540889822 times.
✗ Branch 1 not taken.
1540889822 CHECK(scr);
582 1540889822 return scr;
583 }
584
585 841466807 mapscr* get_scr(int screen)
586 {
587 841466807 return get_scr(cur_map, screen);
588 }
589
590 // Returns null if active screen does not exist.
591 1726717884 mapscr* get_scr_maybe(int map, int screen)
592 {
593 DCHECK_RANGE_INCLUSIVE(screen, 0, 135);
594
595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1726717884 times.
1726717884 if (map == cur_map)
596 {
597
2/2
✓ Branch 0 taken 1705891910 times.
✓ Branch 1 taken 20825974 times.
1726717884 if (screen == cur_screen)
598 1705891910 return origin_scr;
599
600 20825974 int index = screen*7;
601
2/2
✓ Branch 0 taken 20802272 times.
✓ Branch 1 taken 23702 times.
20825974 if (temporary_screens[index])
602 20802272 return temporary_screens[index];
603
604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23702 times.
23702 if (screen == home_screen)
605 return special_warp_return_scr;
606 23702 }
607
608
4/6
✓ Branch 0 taken 23700 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 23700 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 23700 times.
23702 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
609 {
610 23700 int index = screen*7;
611
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23700 times.
23700 if (FFCore.ScrollingScreensAll[index])
612 23700 return FFCore.ScrollingScreensAll[index];
613 }
614
615 2 return nullptr;
616 1726717884 }
617
618 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
619 6985140625 mapscr* get_scr_layer(int map, int screen, int layer)
620 {
621 DCHECK_LAYER_ZERO_INDEX(layer);
622
2/2
✓ Branch 0 taken 6288656226 times.
✓ Branch 1 taken 696484399 times.
6985140625 if (layer == 0)
623 696484399 return get_scr(map, screen);
624
625
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6288656226 times.
6288656226 if (map == cur_map)
626 {
627 6288656226 int index = screen*7 + layer;
628
2/2
✓ Branch 0 taken 6288512166 times.
✓ Branch 1 taken 144060 times.
6288656226 if (temporary_screens[index])
629 6288512166 return temporary_screens[index];
630
631
2/2
✓ Branch 0 taken 1860 times.
✓ Branch 1 taken 142200 times.
144060 if (screen == home_screen)
632 1860 return &special_warp_return_scrs[layer];
633 142200 }
634
635
1/2
✓ Branch 0 taken 142200 times.
✗ Branch 1 not taken.
142200 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
636 {
637 142200 int index = screen*7 + layer;
638
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142200 times.
142200 if (FFCore.ScrollingScreensAll[index])
639 142200 return FFCore.ScrollingScreensAll[index];
640 }
641
642 NOTREACHED();
643 6985140625 }
644
645 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
646 6563176207 mapscr* get_scr_layer(int screen, int layer)
647 {
648 6563176207 return get_scr_layer(cur_map, screen, layer);
649 }
650
651 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
652 // Return nullptr if screen is not valid.
653 418984061 mapscr* get_scr_layer_valid(int screen, int layer)
654 {
655
2/2
✓ Branch 0 taken 98840427 times.
✓ Branch 1 taken 320143634 times.
418984061 if (mapscr* scr = get_scr_layer(cur_map, screen, layer); scr->is_valid())
656 98840427 return scr;
657 320143634 return nullptr;
658 418984061 }
659
660 401 mapscr* get_scr_current_region_dir(int screen, direction dir)
661 {
662 401 int x = get_region_relative_dx(screen);
663 401 int y = get_region_relative_dy(screen);
664
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
401 if (dir == left && x == 0)
665 71 return nullptr;
666
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
330 if (dir == right && x == 15)
667 return nullptr;
668
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
330 if (dir == down && y == 7)
669 return nullptr;
670
3/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
330 if (dir == up && y == 0)
671 189 return nullptr;
672
673 141 screen = screen_index_direction(screen, dir);
674
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (is_in_current_region(screen))
675 return get_scr(screen);
676
677 141 return nullptr;
678 401 }
679
680 183838 ffc_handle_t get_ffc_handle(ffc_id_t id)
681 {
682 183838 uint8_t screen = get_screen_for_region_index_offset(id / MAXFFCS);
683 183838 uint8_t i = id % MAXFFCS;
684 183838 mapscr* scr = get_scr(screen);
685 183838 ffcdata* ffc = &scr->getFFC(id % MAXFFCS);
686 183838 return {scr, screen, id, i, ffc};
687 }
688
689 34571 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen, int x, int y)
690 {
691 34571 x += get_region_relative_dx(screen) * 256;
692 34571 y += get_region_relative_dy(screen) * 176;
693 34571 return {x, y};
694 }
695
696 1056034 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen)
697 {
698 1056034 int x = get_region_relative_dx(screen) * 256;
699 1056034 int y = get_region_relative_dy(screen) * 176;
700 1056034 return {x, y};
701 }
702
703 12687660391 int32_t COMBOPOS(int32_t x, int32_t y)
704 {
705 DCHECK(x >= 0 && x < 256 && y >= 0 && y < 176);
706 12687660391 return (y & 0xF0) + (x >> 4);
707 }
708 int32_t COMBOPOS_B(int32_t x, int32_t y)
709 {
710 if(unsigned(x) >= 256 || unsigned(y) >= 176)
711 return -1;
712 return (y & 0xF0) + (x >> 4);
713 }
714 3953286108 int32_t COMBOX(int32_t pos)
715 {
716 3953286108 return pos % 16 * 16;
717 }
718 3953286108 int32_t COMBOY(int32_t pos)
719 {
720 3953286108 return pos & 0xF0;
721 }
722
723 116942863 rpos_t COMBOPOS_REGION(int32_t x, int32_t y)
724 {
725
2/2
✓ Branch 0 taken 89784911 times.
✓ Branch 1 taken 27157952 times.
116942863 if (!is_in_scrolling_region())
726 89784911 return (rpos_t) COMBOPOS(x, y);
727
728 DCHECK(is_in_world_bounds(x, y));
729 27157952 int scr_dx = x / (16*16);
730 27157952 int scr_dy = y / (11*16);
731 27157952 int pos = COMBOPOS(x%256, y%176);
732 27157952 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
733 116942863 }
734 6958298395 rpos_t COMBOPOS_REGION_B(int32_t x, int32_t y)
735 {
736
2/2
✓ Branch 0 taken 1553141 times.
✓ Branch 1 taken 6956745254 times.
6958298395 if (!is_in_world_bounds(x, y))
737 1553141 return rpos_t::None;
738
739 6956745254 int scr_dx = x / (16*16);
740 6956745254 int scr_dy = y / (11*16);
741 6956745254 int pos = COMBOPOS(x%256, y%176);
742 6956745254 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
743 6958298395 }
744 28725348 std::pair<int32_t, int32_t> COMBOXY_REGION(rpos_t rpos)
745 {
746 28725348 int scr_index = static_cast<int32_t>(rpos) / 176;
747 28725348 int scr_dx = scr_index % cur_region.screen_width;
748 28725348 int scr_dy = scr_index / cur_region.screen_width;
749 28725348 int pos = RPOS_TO_POS(rpos);
750 28725348 int x = scr_dx*16*16 + COMBOX(pos);
751 28725348 int y = scr_dy*11*16 + COMBOY(pos);
752 28725348 return {x, y};
753 }
754 182363 int32_t COMBOX_REGION(rpos_t rpos)
755 {
756 182363 auto [x, y] = COMBOXY_REGION(rpos);
757 182363 return x;
758 }
759 134192 int32_t COMBOY_REGION(rpos_t rpos)
760 {
761 134192 auto [x, y] = COMBOXY_REGION(rpos);
762 134192 return y;
763 }
764
765 70177 rpos_t COMBOPOS_REGION_INDEX(int32_t x, int32_t y)
766 {
767 DCHECK(is_in_world_bounds(x, y));
768
1/2
✓ Branch 0 taken 70177 times.
✗ Branch 1 not taken.
70177 if (!is_in_scrolling_region())
769 70177 return (rpos_t)(x + y * 16);
770
771 int scr_dx = x / 16;
772 int scr_dy = y / 11;
773 x %= 16;
774 y %= 11;
775 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + x + y * 16);
776 70177 }
777 70632 std::pair<int32_t, int32_t> COMBOXY_REGION_INDEX(rpos_t rpos)
778 {
779 70632 int scr_index = static_cast<int32_t>(rpos) / 176;
780 70632 int scr_dx = scr_index % cur_region.screen_width;
781 70632 int scr_dy = scr_index / cur_region.screen_width;
782 70632 int pos = RPOS_TO_POS(rpos);
783 70632 int x = scr_dx*16 + pos%16;
784 70632 int y = scr_dy*11 + pos/16;
785 70632 return {x, y};
786 }
787
788 92297163 int32_t mapind(int32_t map, int32_t scr)
789 {
790 92297163 return map * MAPSCRSNORMAL + scr;
791 }
792
793 FONT *get_zc_font(int index);
794
795 extern sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations;
796 extern movingblock mblock2; //mblock[4]?
797 extern portal mirror_portal;
798
799 void Z_message_d(const char *format,...)
800 {
801 #ifdef _DEBUG
802 char buf[512];
803 va_list ap;
804 va_start(ap, format);
805 vsprintf(buf, format, ap);
806 va_end(ap);
807
808 al_trace("%s",buf);
809 #else
810 format=format;
811 #endif
812 }
813
814
815
816 bool checktrigger=false;
817
818 void debugging_box(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
819 {
820 //reference/optimization: the start of the unused drawing command index can now be queried. -Gleeok
821 int32_t index = script_drawing_commands.GetNext();
822
823 if(index < 0)
824 return;
825
826 int32_t *sdci = &script_drawing_commands[index][0];
827
828 sdci[0] = RECTR;
829 sdci[1] = 30000;
830 sdci[2] = x1*10000;
831 sdci[3] = y1*10000;
832 sdci[4] = x2*10000;
833 sdci[5] = y2*10000;
834 sdci[6] = 10000;
835 sdci[7] = 10000;
836 sdci[8] = 0;
837 sdci[9] = 0;
838 sdci[10] = 0;
839 sdci[11] = 10000;
840 sdci[12] = 1280000;
841 }
842
843 void clear_dmap(word i)
844 {
845 DMaps[i].clear();
846 }
847
848 void clear_dmaps()
849 {
850 for(int32_t i=0; i<MAXDMAPS; i++)
851 {
852 clear_dmap(i);
853 }
854 }
855
856 235175450 int32_t isdungeon(int32_t dmap, int32_t screen)
857 {
858
2/2
✓ Branch 0 taken 235128090 times.
✓ Branch 1 taken 47360 times.
235175450 if (dmap < 0) dmap = cur_dmap;
859
860 // dungeons can have any dlevel above 0
861
2/2
✓ Branch 0 taken 133926005 times.
✓ Branch 1 taken 101249445 times.
235175450 if((DMaps[dmap].type&dmfTYPE) == dmDNGN)
862 {
863
2/2
✓ Branch 0 taken 9961 times.
✓ Branch 1 taken 101239484 times.
101249445 if (get_canonical_scr(cur_map, screen)->flags6&fCAVEROOM)
864 9961 return 0;
865
866 101239484 return 1;
867 }
868
869 // dlevels that aren't dungeons are caves
870
2/2
✓ Branch 0 taken 36827 times.
✓ Branch 1 taken 133889178 times.
133926005 if (get_canonical_scr(cur_map, screen)->flags6&fDUNGEONROOM)
871 36827 return 1;
872
873 133889178 return 0;
874 235175450 }
875
876 43123809 int32_t isdungeon(int32_t screen)
877 {
878 43123809 return isdungeon(cur_dmap, screen);
879 }
880
881 191919507 int32_t isdungeon()
882 {
883 191919507 return isdungeon(cur_dmap, Hero.current_screen);
884 }
885
886 92456 bool canPermSecret(int32_t dmap, int32_t screen)
887 {
888
2/2
✓ Branch 0 taken 13910 times.
✓ Branch 1 taken 78546 times.
92456 return (!isdungeon(dmap, screen) || get_qr(qr_DUNGEON_DMAPS_PERM_SECRETS));
889 }
890
891 1263589280 int32_t MAPCOMBO(int32_t x, int32_t y)
892 {
893 1263589280 x = vbound(x, 0, world_w-1);
894 1263589280 y = vbound(y, 0, world_h-1);
895 1263589280 int pos = COMBOPOS(x%256, y%176);
896 1263589280 mapscr* scr = get_scr_for_world_xy(x, y);
897 1263589280 return scr->data[pos];
898 }
899
900 //specific layers 1 to 6
901 1488313646 int32_t MAPCOMBOL(int32_t layer,int32_t x,int32_t y)
902 {
903 DCHECK(layer >= 1 && layer <= 6);
904
3/4
✓ Branch 0 taken 1468410192 times.
✓ Branch 1 taken 19903454 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1468410192 times.
1488313646 if (!is_in_world_bounds(x, y) || layer <= 0)
905 19903454 return 0;
906
907 1468410192 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
908
2/2
✓ Branch 0 taken 472740182 times.
✓ Branch 1 taken 995670010 times.
1468410192 if (!m->is_valid())
909 995670010 return 0;
910
911 472740182 int pos = COMBOPOS(x%256, y%176);
912 472740182 return m->data[pos];
913 1488313646 }
914
915 int32_t MAPCSETL(int32_t layer,int32_t x,int32_t y)
916 {
917 DCHECK(layer >= 1 && layer <= 6);
918 if (!is_in_world_bounds(x, y) || layer <= 0)
919 return 0;
920
921 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
922 if (!m->is_valid())
923 return 0;
924
925 int pos = COMBOPOS(x%256, y%176);
926 return m->cset[pos];
927 }
928
929 372352 int32_t MAPFLAGL(int32_t layer,int32_t x,int32_t y)
930 {
931 DCHECK(layer >= 1 && layer <= 6);
932
2/4
✓ Branch 0 taken 372352 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 372352 times.
372352 if (!is_in_world_bounds(x, y) || layer <= 0)
933 return 0;
934
935 372352 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
936
2/2
✓ Branch 0 taken 345286 times.
✓ Branch 1 taken 27066 times.
372352 if (!m->is_valid())
937 27066 return 0;
938
939 345286 int pos = COMBOPOS(x%256, y%176);
940 345286 return m->sflag[pos];
941 372352 }
942
943 40979 int32_t COMBOTYPEL(int32_t layer,int32_t x,int32_t y)
944 {
945 DCHECK(layer >= 1 && layer <= 6);
946
2/4
✓ Branch 0 taken 40979 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40979 times.
40979 if (!is_in_world_bounds(x, y) || layer <= 0)
947 return 0;
948
949 40979 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
950
2/2
✓ Branch 0 taken 40624 times.
✓ Branch 1 taken 355 times.
40979 if (!m->is_valid())
951 355 return 0;
952
953 40624 int pos = COMBOPOS(x%256, y%176);
954 40624 return combobuf[m->data[pos]].type;
955 40979 }
956
957 371064 int32_t MAPCOMBOFLAGL(int32_t layer,int32_t x,int32_t y)
958 {
959 DCHECK(layer >= 1 && layer <= 6);
960
2/4
✓ Branch 0 taken 371064 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 371064 times.
371064 if (!is_in_world_bounds(x, y) || layer <= 0)
961 return 0;
962
963 371064 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
964
2/2
✓ Branch 0 taken 343998 times.
✓ Branch 1 taken 27066 times.
371064 if (!m->is_valid())
965 27066 return 0;
966
967 343998 int pos = COMBOPOS(x%256, y%176);
968 343998 return combobuf[m->data[pos]].flag;
969 371064 }
970
971
972 // True if the FFC covers x, y and is not ethereal or a changer.
973 2675848580 bool ffcIsAt(const ffc_handle_t& ffc_handle, int32_t x, int32_t y)
974 {
975
2/2
✓ Branch 0 taken 750008244 times.
✓ Branch 1 taken 1925840336 times.
2675848580 if (ffc_handle.data()<=0)
976 750008244 return false;
977
978
2/2
✓ Branch 0 taken 314946537 times.
✓ Branch 1 taken 1610893799 times.
1925840336 if((ffc_handle.ffc->flags&(ffc_changer|ffc_ethereal))!=0)
979 314946537 return false;
980
981 1610893799 int32_t fx=ffc_handle.ffc->x.getInt();
982
4/4
✓ Branch 0 taken 1108805738 times.
✓ Branch 1 taken 502088061 times.
✓ Branch 2 taken 990415197 times.
✓ Branch 3 taken 118390541 times.
1610893799 if(x<fx || x>fx+(ffc_handle.scr->ffEffectWidth(ffc_handle.i)-1)) // FFC sizes are weird.
983 1492503258 return false;
984
985 118390541 int32_t fy=ffc_handle.ffc->y.getInt();
986
4/4
✓ Branch 0 taken 84638375 times.
✓ Branch 1 taken 33752166 times.
✓ Branch 2 taken 64688475 times.
✓ Branch 3 taken 19949900 times.
118390541 if(y<fy || y>fy+(ffc_handle.scr->ffEffectHeight(ffc_handle.i)-1))
987 98440641 return false;
988
989 19949900 return true;
990 2675848580 }
991
992 829686160 int32_t MAPFFCOMBO(int32_t x,int32_t y)
993 {
994
2/2
✓ Branch 0 taken 11864553 times.
✓ Branch 1 taken 817821607 times.
829686160 if (auto ffc_handle = getFFCAt(x, y))
995 11864553 return ffc_handle->data();
996 817821607 return 0;
997 829686160 }
998
999 207232 int32_t MAPCSET(int32_t x, int32_t y)
1000 {
1001
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207232 times.
207232 if (!is_in_world_bounds(x, y))
1002 return 0;
1003 207232 mapscr* scr = get_scr_for_world_xy(x, y);
1004 207232 int pos = COMBOPOS(x%256, y%176);
1005 207232 return scr->cset[pos];
1006 207232 }
1007
1008 87058260 int32_t MAPFLAG(int32_t x, int32_t y)
1009 {
1010
2/2
✓ Branch 0 taken 28507 times.
✓ Branch 1 taken 87029753 times.
87058260 if (!is_in_world_bounds(x, y))
1011 28507 return 0;
1012 87029753 mapscr* scr = get_scr_for_world_xy(x, y);
1013 87029753 int pos = COMBOPOS(x%256, y%176);
1014 87029753 return scr->sflag[pos];
1015 87058260 }
1016
1017 95535040 int32_t COMBOTYPE(int32_t x,int32_t y)
1018 {
1019 95535040 int32_t b=1;
1020
2/2
✓ Branch 0 taken 64699716 times.
✓ Branch 1 taken 30835324 times.
95535040 if(x&8) b<<=2;
1021
2/2
✓ Branch 0 taken 60202941 times.
✓ Branch 1 taken 35332099 times.
95535040 if(y&8) b<<=1;
1022
1023
2/2
✓ Branch 0 taken 191062333 times.
✓ Branch 1 taken 95519803 times.
286582136 for (int32_t i = 0; i <= 1; ++i)
1024 {
1025
2/2
✓ Branch 0 taken 158746666 times.
✓ Branch 1 taken 32315667 times.
191062333 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1026 {
1027
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 158746666 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
158746666 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x, y, i)) return cNONE;
1028 158746666 }
1029 else
1030 {
1031
4/4
✓ Branch 0 taken 18389 times.
✓ Branch 1 taken 32297278 times.
✓ Branch 2 taken 3152 times.
✓ Branch 3 taken 15237 times.
32315667 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x, y, i)) return cNONE;
1032 }
1033 191047096 }
1034
1035 95519803 newcombo const& cmb = combobuf[MAPCOMBO(x,y)];
1036
5/6
✓ Branch 0 taken 3536077 times.
✓ Branch 1 taken 91983726 times.
✓ Branch 2 taken 1909096 times.
✓ Branch 3 taken 1626981 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1909096 times.
95519803 if (cmb.type == cWATER && (cmb.walk&b) && ((cmb.walk>>4)&b))
1037 {
1038
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1909096 times.
1909096 if(cmb.usrflags&cflag4) return cSHALLOWWATER;
1039
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1909096 times.
1909096 if(cmb.usrflags&cflag3) return cNONE;
1040 1909096 }
1041 95519803 return cmb.type;
1042 95535040 }
1043
1044 59029490 int32_t FFCOMBOTYPE(int32_t x,int32_t y)
1045 {
1046 59029490 return combobuf[MAPFFCOMBO(x,y)].type;
1047 }
1048
1049 7138093 int32_t FFORCOMBO(int32_t x, int32_t y)
1050 {
1051
2/2
✓ Branch 0 taken 78428 times.
✓ Branch 1 taken 7059665 times.
7138093 if (auto ffc_handle = getFFCAt(x, y))
1052 78428 return ffc_handle->data();
1053
1054 7059665 return MAPCOMBO(x,y);
1055 7138093 }
1056
1057 int32_t FFORCOMBOTYPE(int32_t x, int32_t y)
1058 {
1059 for (int32_t i = 0; i <= 1; ++i)
1060 {
1061 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1062 {
1063 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1064 }
1065 else
1066 {
1067 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1068 }
1069 }
1070 int32_t b=1;
1071
1072 if(x&8) b<<=2;
1073
1074 if(y&8) b<<=1;
1075 newcombo const& cmb = combobuf[FFORCOMBO(x,y)];
1076 if (cmb.type == cWATER && (cmb.usrflags&cflag4) && (cmb.walk&b)) return cSHALLOWWATER;
1077 if (cmb.type == cWATER && (cmb.usrflags&cflag3) && (cmb.walk&b)) return cNONE;
1078 return cmb.type;
1079 }
1080
1081 int32_t FFORCOMBO_L(int32_t layer, int32_t x, int32_t y)
1082 {
1083 if (auto ffc_handle = getFFCAt(x, y))
1084 return ffc_handle->data();
1085
1086 return layer ? MAPCOMBOL(layer, x, y) : MAPCOMBO(x,y);
1087 }
1088
1089 int32_t FFORCOMBOTYPE_L(int32_t layer, int32_t x, int32_t y)
1090 {
1091 return combobuf[FFORCOMBO_L(layer,x,y)].type;
1092 }
1093
1094 83411065 int32_t MAPCOMBOFLAG(int32_t x,int32_t y)
1095 {
1096
2/2
✓ Branch 0 taken 28219 times.
✓ Branch 1 taken 83382846 times.
83411065 if (!is_in_world_bounds(x, y))
1097 28219 return 0;
1098
1099 83382846 mapscr* scr = get_scr_for_world_xy(x, y);
1100 83382846 int pos = COMBOPOS(x%256, y%176);
1101 83382846 return combobuf[scr->data[pos]].flag;
1102 83411065 }
1103
1104 68111964 int32_t MAPFFCOMBOFLAG(int32_t x,int32_t y)
1105 {
1106
2/2
✓ Branch 0 taken 777663 times.
✓ Branch 1 taken 67334301 times.
68111964 if (auto ffc_handle = getFFCAt(x, y))
1107 777663 return ffc_handle->cflag();
1108
1109 67334301 return 0;
1110 68111964 }
1111
1112 1237529476 std::optional<ffc_handle_t> getFFCAt(int32_t x, int32_t y)
1113 {
1114 2784492011 return find_ffc([&](const ffc_handle_t& ffc_handle) {
1115 1546962535 return ffcIsAt(ffc_handle, x, y);
1116 });
1117 }
1118
1119 3051 int32_t MAPCOMBO(const rpos_handle_t& rpos_handle)
1120 {
1121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3051 times.
3051 if (!rpos_handle.scr->is_valid()) return 0;
1122 3051 return rpos_handle.data();
1123 3051 }
1124
1125 3016793581 int32_t MAPCOMBO2(int32_t layer, int32_t x, int32_t y)
1126 {
1127 DCHECK_LAYER_NEG1_INDEX(layer);
1128
2/2
✓ Branch 0 taken 22065451 times.
✓ Branch 1 taken 2994728130 times.
3016793581 if (!is_in_world_bounds(x, y)) return 0;
1129
2/2
✓ Branch 0 taken 2895639259 times.
✓ Branch 1 taken 99088871 times.
2994728130 if (layer == -1) return MAPCOMBO(x, y);
1130
1131 2895639259 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1132
2/2
✓ Branch 0 taken 1795213073 times.
✓ Branch 1 taken 1100426186 times.
2895639259 if (!rpos_handle.scr->is_valid()) return 0;
1133
1134 1100426186 return rpos_handle.data();
1135 3016793581 }
1136
1137 19160358 static void _handle_screen_load_trigger(const combined_handle_t& handle)
1138 {
1139 19160358 auto cid = handle.data();
1140 19160358 auto* cmb = &handle.combo();
1141 19160358 bool done = false;
1142 19160358 std::set<int32_t> visited;
1143
2/2
✓ Branch 0 taken 19160358 times.
✓ Branch 1 taken 19160358 times.
38320716 while(!done)
1144 {
1145
2/4
✓ Branch 0 taken 19160358 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19160358 times.
19160358 if(visited.contains(cid))
1146 {
1147 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
1148 break; // prevent infinite loop
1149 }
1150
1/2
✓ Branch 0 taken 19160358 times.
✗ Branch 1 not taken.
19160358 visited.insert(cid);
1151
1152 19160358 done = true; // don't loop again unless something changes
1153
1/2
✓ Branch 0 taken 19160358 times.
✗ Branch 1 not taken.
20044499 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
1154 884141 return trig.trigger_flags.get(TRIGFLAG_SCREENLOAD);
1155 });
1156
2/4
✓ Branch 0 taken 19160358 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19160358 times.
19160358 if(handle.data() != cid)
1157 {
1158 cid = handle.data();
1159 cmb = &handle.combo();
1160 done = false; // loop again for the new combo
1161 }
1162 }
1163 19160358 }
1164 52903 static void handle_screen_load_trigger(const screen_handles_t& screen_handles)
1165 {
1166 52903 for_every_combo_in_screen(screen_handles, _handle_screen_load_trigger);
1167 52903 }
1168 36493 void handle_region_load_trigger()
1169 {
1170
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 36341 times.
36493 if (is_in_scrolling_region())
1171 {
1172
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 19456 times.
19608 for (int screen = 0; screen < 128; screen++)
1173 {
1174
2/2
✓ Branch 0 taken 18156 times.
✓ Branch 1 taken 1300 times.
19456 if (is_in_current_region(screen))
1175 1300 handle_screen_load_trigger(create_screen_handles_one(get_scr(screen)));
1176 19456 }
1177 152 }
1178 36341 else handle_screen_load_trigger(create_screen_handles_one(get_scr(Hero.current_screen)));
1179 36493 }
1180
1181 15262 static void apply_state_changes_to_screen(mapscr& scr, int32_t map, int32_t screen, int32_t flags, bool secrets_do_replay_comment)
1182 {
1183 15262 auto screen_handles = create_screen_handles_one(&scr);
1184
1185
3/4
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 14723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 539 times.
15262 if ((flags & mSECRET) && canPermSecret(cur_dmap, screen))
1186 {
1187 539 reveal_hidden_stairs(&scr, screen, false);
1188 539 bool do_layers = false;
1189 539 bool from_active_screen = false;
1190 539 trigger_secrets_for_screen_internal(screen_handles, do_layers, from_active_screen, -3, secrets_do_replay_comment);
1191 539 }
1192
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if (flags & mLIGHTBEAM)
1193 {
1194 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
1195 if (rpos_handle.ctype() == cLIGHTTARGET)
1196 {
1197 if (!(rpos_handle.combo().usrflags&cflag1)) //Unlit version
1198 rpos_handle.increment_data();
1199 }
1200 });
1201 }
1202
1203 15262 int lvl = DMaps[cur_dmap].level;
1204 15262 toggle_switches(game->lvlswitches[lvl], true, screen_handles);
1205 15262 toggle_gswitches_load(screen_handles);
1206
1207
2/2
✓ Branch 0 taken 15170 times.
✓ Branch 1 taken 92 times.
15262 if(flags&mLOCKBLOCK) // if special stuff done before
1208 {
1209 92 remove_screenstatecombos2(screen_handles, false, cLOCKBLOCK, cLOCKBLOCK2);
1210 92 }
1211
1212
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSLOCKBLOCK) // if special stuff done before
1213 {
1214 remove_screenstatecombos2(screen_handles, false, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
1215 }
1216
1217
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1218 {
1219 remove_screenstatecombos2(screen_handles, false, cCHEST, cCHEST2);
1220 }
1221
1222
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1223 {
1224 remove_screenstatecombos2(screen_handles, false, cLOCKEDCHEST, cLOCKEDCHEST2);
1225 }
1226
1227
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSCHEST) // if special stuff done before
1228 {
1229 remove_screenstatecombos2(screen_handles, false, cBOSSCHEST, cBOSSCHEST2);
1230 }
1231
1232
1233 15262 int mi = mapind(map, screen);
1234 15262 clear_xdoors_mi(screen_handles, mi);
1235 15262 clear_xstatecombos_mi(screen_handles, mi);
1236
1237 15262 handle_screen_load_trigger(screen_handles);
1238 15262 }
1239
1240 40981 std::optional<mapscr> load_temp_mapscr_and_apply_secrets(int32_t map, int32_t screen, int32_t layer, bool secrets, bool secrets_do_replay_comment)
1241 {
1242
2/4
✓ Branch 0 taken 40981 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40981 times.
40981 if (map < 0 || screen < 0)
1243 return std::nullopt;
1244
1245 40981 const mapscr* source = get_canonical_scr(map, screen);
1246
2/2
✓ Branch 0 taken 39256 times.
✓ Branch 1 taken 1725 times.
40981 if (!source->is_valid())
1247 1725 return std::nullopt;
1248
1249
2/2
✓ Branch 0 taken 7936 times.
✓ Branch 1 taken 31320 times.
39256 if (layer >= 0)
1250 {
1251
2/2
✓ Branch 0 taken 23994 times.
✓ Branch 1 taken 7326 times.
31320 if (source->layermap[layer] <= 0)
1252 23994 return std::nullopt;
1253
1254 7326 source = get_canonical_scr(source->layermap[layer] - 1, source->layerscreen[layer]);
1255
1/2
✓ Branch 0 taken 7326 times.
✗ Branch 1 not taken.
7326 if (!source->is_valid())
1256 return std::nullopt;
1257 7326 }
1258
1259
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 int flags = secrets ? game->maps[mapind(map, screen)] : 0;
1260 15262 mapscr scr = *source;
1261
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 apply_state_changes_to_screen(scr, map, screen, flags, secrets_do_replay_comment);
1262
1263
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 return scr;
1264 40981 }
1265
1266 14990 static int32_t MAPCOMBO3_impl(int32_t map, int32_t screen, int32_t layer, int32_t pos, bool secrets)
1267 {
1268
2/4
✓ Branch 0 taken 14990 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14990 times.
14990 if (map < 0 || screen < 0) return 0;
1269
1270
2/4
✓ Branch 0 taken 14990 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14990 times.
14990 if(pos>175 || pos < 0)
1271 return 0;
1272
1273 // TODO: consider caching this (invalidate on any modification via scripting, or anything
1274 // `apply_state_changes_to_screen` checks).
1275
4/5
✓ Branch 0 taken 4736 times.
✓ Branch 1 taken 10254 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4736 times.
✓ Branch 4 taken 10254 times.
19726 if (auto s = load_temp_mapscr_and_apply_secrets(map, screen, layer, secrets))
1276 4736 return s->data[pos];
1277
1278 10254 return 0;
1279 14990 }
1280
1281 // Read from the current temporary screens or, if (map, screen) is not loaded,
1282 // load that screen and apply the relevant secrets before evaluating the combo at that position.
1283 251040362 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets)
1284 {
1285 DCHECK_LAYER_NEG1_INDEX(layer);
1286 DCHECK(map >= 0 && screen >= 0);
1287
1288
2/2
✓ Branch 0 taken 251025372 times.
✓ Branch 1 taken 14990 times.
251040362 if (is_in_current_region(map, screen)) return MAPCOMBO2(layer, x, y);
1289
1290 // Screen is not in the current region, so we have to load and trigger some secrets.
1291 14990 int pos = COMBOPOS(x, y);
1292 14990 return MAPCOMBO3_impl(map, screen, layer, pos, secrets);
1293 251040362 }
1294
1295 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, rpos_t rpos, bool secrets)
1296 {
1297 DCHECK_LAYER_NEG1_INDEX(layer);
1298 DCHECK(map >= 0 && screen >= 0);
1299 DCHECK(is_valid_rpos(rpos));
1300
1301 if (is_in_current_region(map, screen)) return MAPCOMBO(get_rpos_handle(rpos, layer + 1));
1302
1303 // Screen is not currently loaded, so we have to load and trigger some secrets.
1304 return MAPCOMBO3_impl(map, screen, layer, RPOS_TO_POS(rpos), secrets);
1305 }
1306
1307 int32_t MAPCSET2(int32_t layer,int32_t x,int32_t y)
1308 {
1309 DCHECK_LAYER_NEG1_INDEX(layer);
1310 if (!is_in_world_bounds(x, y))
1311 return 0;
1312 if (layer == -1) return MAPCSET(x, y);
1313
1314 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1315 if (!rpos_handle.scr->is_valid()) return 0;
1316
1317 return rpos_handle.cset();
1318 }
1319
1320 102412110 int32_t MAPFLAG2(int32_t layer,int32_t x,int32_t y)
1321 {
1322 DCHECK_LAYER_NEG1_INDEX(layer);
1323
3/4
✓ Branch 0 taken 5385623 times.
✓ Branch 1 taken 97026487 times.
✓ Branch 2 taken 5385623 times.
✗ Branch 3 not taken.
102412110 if (!get_qr(qr_BUGGED_LAYERED_FLAGS) && (!is_in_world_bounds(x, y)))
1324 return 0;
1325
2/2
✓ Branch 0 taken 84274481 times.
✓ Branch 1 taken 18137629 times.
102412110 if (layer == -1) return MAPFLAG(x, y);
1326
1327 84274481 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1328
2/2
✓ Branch 0 taken 63729953 times.
✓ Branch 1 taken 20544528 times.
84274481 if (!rpos_handle.scr->is_valid()) return 0;
1329
1330 20544528 return rpos_handle.sflag();
1331 102412110 }
1332
1333 int32_t COMBOTYPE2(int32_t layer,int32_t x,int32_t y)
1334 {
1335 if(layer < 1)
1336 {
1337 for (int32_t i = layer+1; i <= 1; ++i)
1338 {
1339 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1340 {
1341 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1342 }
1343 else
1344 {
1345 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1346 }
1347 }
1348 }
1349 if(layer==-1) return COMBOTYPE(x,y);
1350
1351 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1352 if (!rpos_handle.scr->is_valid()) return 0;
1353
1354 return rpos_handle.ctype();
1355 }
1356
1357 // Returns the flag for the combo at the given position.
1358 // This is also known as an "inherent flag".
1359 100578819 int32_t MAPCOMBOFLAG2(int32_t layer,int32_t x,int32_t y)
1360 {
1361 DCHECK_LAYER_NEG1_INDEX(layer);
1362
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 100578531 times.
100578819 if (!is_in_world_bounds(x, y))
1363 288 return 0;
1364
2/2
✓ Branch 0 taken 84177931 times.
✓ Branch 1 taken 16400600 times.
100578531 if (layer == -1) return MAPCOMBOFLAG(x, y);
1365
1366 84177931 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1367
2/2
✓ Branch 0 taken 63748301 times.
✓ Branch 1 taken 20429630 times.
84177931 if (!rpos_handle.scr->is_valid()) return 0;
1368
1369 20429630 return rpos_handle.cflag();
1370 100578819 }
1371
1372 11643971 bool HASFLAG(int32_t flag, int32_t layer, rpos_t rpos)
1373 {
1374 DCHECK_LAYER_ZERO_INDEX(layer);
1375 11643971 auto rpos_handle = get_rpos_handle(rpos, layer);
1376
2/2
✓ Branch 0 taken 4429246 times.
✓ Branch 1 taken 7214725 times.
11643971 if (!rpos_handle.scr->is_valid()) return false;
1377
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 7210160 times.
7214725 if (rpos_handle.sflag() == flag) return true;
1378
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 7172455 times.
7210160 if (rpos_handle.cflag() == flag) return true;
1379 7172455 return false;
1380 11643971 }
1381
1382 1699509 bool HASFLAG_ANY(int32_t flag, rpos_t rpos)
1383 {
1384 DCHECK(is_valid_rpos(rpos));
1385
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1699509 times.
1699509 if (rpos > region_max_rpos) return false;
1386
1387
2/2
✓ Branch 0 taken 11643971 times.
✓ Branch 1 taken 1657239 times.
13301210 for(auto q = 0; q < 7; ++q)
1388 {
1389
2/2
✓ Branch 0 taken 42270 times.
✓ Branch 1 taken 11601701 times.
11643971 if(HASFLAG(flag, q, rpos))
1390 42270 return true;
1391 11601701 }
1392 1657239 return false;
1393 1699509 }
1394
1395 const char *screenstate_string[32] =
1396 {
1397 "Door Up", "Door Down", "Door Left", "Door Right", "Item", "Special Item", "Some Enemies Never Return",
1398 "Temporary No Return", "Lock Blocks", "Boss Lock Blocks", "Chests", "Locked Chests",
1399 "Boss Locked Chests", "Secrets", "Visited", "Light Beams",
1400 "All Enemies Don't Return", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1401 "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1402 };
1403
1404 36562 void eventlog_mapflags()
1405 {
1406 36562 std::ostringstream oss;
1407
1408 36562 int mi = mapind(cur_map, home_screen);
1409
1/2
✓ Branch 0 taken 36562 times.
✗ Branch 1 not taken.
36562 dword g = game->maps[mi];
1410
1411
2/4
✓ Branch 0 taken 36562 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36562 times.
✗ Branch 3 not taken.
36562 oss << fmt::format("Screen ({}, {:02X})", cur_map+1, home_screen);
1412
2/2
✓ Branch 0 taken 15710 times.
✓ Branch 1 taken 20852 times.
36562 if(g) // Main States
1413 {
1414 static const int order[] =
1415 {
1416 mSECRET, mITEM, mSPECIALITEM, mLOCKBLOCK, mBOSSLOCKBLOCK,
1417 mCHEST, mLOCKEDCHEST, mBOSSCHEST,
1418 mDOOR_UP, mDOOR_DOWN, mDOOR_LEFT, mDOOR_RIGHT,
1419 mNEVERRET, mTMPNORET, mLIGHTBEAM, mNO_ENEMIES_RETURN
1420 };
1421
1422
1/2
✓ Branch 0 taken 15710 times.
✗ Branch 1 not taken.
15710 oss << " [";
1423 15710 bool comma = false;
1424
2/2
✓ Branch 0 taken 15710 times.
✓ Branch 1 taken 251360 times.
267070 for(int fl : order)
1425 {
1426
2/2
✓ Branch 0 taken 9640 times.
✓ Branch 1 taken 241720 times.
251360 if(!(g&fl))
1427 241720 continue;
1428 9640 byte ind = byte(log2(double(fl)));
1429
2/2
✓ Branch 0 taken 2072 times.
✓ Branch 1 taken 7568 times.
9640 if(comma)
1430
1/2
✓ Branch 0 taken 2072 times.
✗ Branch 1 not taken.
2072 oss << ", ";
1431
1/2
✓ Branch 0 taken 9640 times.
✗ Branch 1 not taken.
9640 oss << screenstate_string[ind];
1432 9640 comma = true;
1433 }
1434
1/2
✓ Branch 0 taken 15710 times.
✗ Branch 1 not taken.
15710 oss << "]";
1435 15710 }
1436
3/4
✓ Branch 0 taken 36562 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 36506 times.
36562 if(game->xstates[mi]) // ExStates
1437 {
1438
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 oss << " Ex[";
1439 56 bool comma = false;
1440
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 1792 times.
1848 for(byte fl = 0; fl < 32; ++fl)
1441 {
1442
3/4
✓ Branch 0 taken 1792 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 1715 times.
1792 if(game->xstates[mi] & (1<<fl))
1443 {
1444
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 56 times.
77 if(comma)
1445
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 oss << ", ";
1446
1/2
✓ Branch 0 taken 77 times.
✗ Branch 1 not taken.
77 oss << int(fl);
1447 77 comma = true;
1448 77 }
1449 1792 }
1450
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 oss << "]";
1451 56 }
1452 { // ExDoors
1453
2/2
✓ Branch 0 taken 36562 times.
✓ Branch 1 taken 146248 times.
182810 for(int q = 0; q < 4; ++q)
1454 {
1455 146248 bool comma = false;
1456
3/4
✓ Branch 0 taken 146248 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 146246 times.
✓ Branch 3 taken 2 times.
146248 if(auto v = game->xdoors[mi][q])
1457 {
1458
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(comma)
1459 oss << ",";
1460
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else oss << " ExDoor";
1461
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 oss << "[" << dirstr[q];
1462
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 for(int fl = 0; fl < 8; ++fl)
1463
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
19 if(v & (1<<fl))
1464
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 oss << " " << int(fl);
1465
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 oss << "]";
1466 2 comma = true;
1467 2 }
1468 146248 }
1469 }
1470
2/4
✓ Branch 0 taken 36562 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 36562 times.
36562 Z_eventlog("%s\n", oss.str().c_str());
1471 36562 }
1472
1473 // set specific flag
1474 5932 void setmapflag(mapscr* scr, uint32_t flag)
1475 {
1476
2/2
✓ Branch 0 taken 5919 times.
✓ Branch 1 taken 13 times.
5932 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1477 5932 int mi = mapind(cur_map, scr->screen);
1478 5932 setmapflag_mi(scr, mi, flag);
1479 5932 }
1480 57 void setmapflag_homescr(uint32_t flag)
1481 {
1482 57 int mi = mapind(cur_map, home_screen);
1483 57 setmapflag_mi(origin_scr, mi, flag);
1484 57 }
1485 2065 void setmapflag_mi(int32_t mi, uint32_t flag)
1486 {
1487 2065 byte cscr = mi&((1<<7)-1);
1488 2065 byte cmap = (mi>>7);
1489 2065 mapscr* scr = origin_scr;
1490
2/2
✓ Branch 0 taken 835 times.
✓ Branch 1 taken 1230 times.
2065 if (is_in_current_region(cmap, cscr))
1491 1230 scr = get_scr(cmap, cscr);
1492
1493 2065 setmapflag_mi(scr, mi, flag);
1494 2065 }
1495
1496 8877 static void log_state_change(int map, int screen, std::string action)
1497 {
1498
6/6
✓ Branch 0 taken 1937 times.
✓ Branch 1 taken 6940 times.
✓ Branch 2 taken 996 times.
✓ Branch 3 taken 941 times.
✓ Branch 4 taken 352 times.
✓ Branch 5 taken 644 times.
8877 if (is_in_current_region(map, screen) || (map == cur_map && screen == home_screen))
1499 7292 Z_eventlog("[Map %d, Screen %02X (current)] %s\n", map + 1, screen, action.c_str());
1500 else
1501 1585 Z_eventlog("[Map %d, Screen %02X] %s\n", map + 1, screen, action.c_str());
1502 8877 }
1503
1504 8054 void setmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag)
1505 {
1506 8054 byte cscr = mi&((1<<7)-1);
1507 8054 byte cmap = (mi>>7);
1508
1509 8054 double temp=log2((double)flag);
1510
1/2
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
8054 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1511 8054 const char* replay_state_string = state_string;
1512
2/2
✓ Branch 0 taken 7534 times.
✓ Branch 1 taken 520 times.
8054 if(temp == 6) replay_state_string = "No Return";
1513
1514
3/4
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1596 times.
✓ Branch 3 taken 6458 times.
8054 if (replay_is_active() && !(game->maps[mi] & flag))
1515
1/2
✓ Branch 0 taken 6458 times.
✗ Branch 1 not taken.
6458 replay_step_comment(fmt::format("map {} scr {} flag {}", cmap, cscr, replay_state_string));
1516 8054 game->maps[mi] |= flag;
1517
1/2
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
8054 log_state_change(cmap, cscr, fmt::format("State set: {}", state_string));
1518
1519
2/2
✓ Branch 0 taken 2518 times.
✓ Branch 1 taken 5536 times.
8054 if((scr->nocarry&flag)!=flag)
1520 {
1521 5536 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1522 5536 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1523
1524 5536 std::vector<int32_t> done;
1525
2/2
✓ Branch 0 taken 5423 times.
✓ Branch 1 taken 113 times.
5536 bool looped = (nmap==cmap+1 && nscr==cscr);
1526
1527
6/6
✓ Branch 0 taken 458 times.
✓ Branch 1 taken 5485 times.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 407 times.
✓ Branch 4 taken 407 times.
✓ Branch 5 taken 5536 times.
5943 while((nmap!=0) && !looped && !(nscr>=128))
1528 {
1529
3/4
✓ Branch 0 taken 407 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 191 times.
✓ Branch 3 taken 216 times.
407 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1530 {
1531
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 log_state_change(nmap, nscr, "State change carried over");
1532
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 if (replay_is_active())
1533
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 replay_step_comment(fmt::format("map {} scr {} flag {} carry", nmap, nscr, replay_state_string));
1534
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 game->maps[((nmap-1)<<7)+nscr] |= flag;
1535 216 }
1536
1537 407 cmap=nmap;
1538 407 cscr=nscr;
1539 407 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1540 407 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1541
1542
2/2
✓ Branch 0 taken 916 times.
✓ Branch 1 taken 407 times.
1323 for(auto it = done.begin(); it != done.end(); it++)
1543 {
1544
2/2
✓ Branch 0 taken 865 times.
✓ Branch 1 taken 51 times.
916 if(*it == ((nmap-1)<<7)+nscr)
1545 51 looped = true;
1546 916 }
1547
1548
1/2
✓ Branch 0 taken 407 times.
✗ Branch 1 not taken.
407 done.push_back(((nmap-1)<<7)+nscr);
1549 }
1550 5536 }
1551 8054 }
1552
1553 void unsetmapflag_home(uint32_t flag, bool anyflag)
1554 {
1555 int mi = mapind(cur_map, home_screen);
1556 unsetmapflag_mi(origin_scr, mi, flag, anyflag);
1557 }
1558
1559 void unsetmapflag(mapscr* scr, uint32_t flag, bool anyflag)
1560 {
1561 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1562 int mi = mapind(cur_map, scr->screen);
1563 unsetmapflag_mi(scr, mi, flag, anyflag);
1564 }
1565
1566 471 void unsetmapflag_mi(int32_t mi, uint32_t flag, bool anyflag)
1567 {
1568 471 byte cscr = mi&((1<<7)-1);
1569 471 byte cmap = (mi>>7);
1570 471 mapscr* scr = origin_scr;
1571
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if (is_in_current_region(cmap, cscr))
1572 11 scr = get_scr(cmap, cscr);
1573
1574 471 unsetmapflag_mi(scr, mi, flag, anyflag);
1575 471 }
1576
1577 471 void unsetmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag, bool anyflag)
1578 {
1579 471 byte cscr = mi&((1<<7)-1);
1580 471 byte cmap = (mi>>7);
1581
1582
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if(anyflag)
1583 460 game->maps[mi] &= ~flag;
1584
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 else if(flag==mITEM || flag==mSPECIALITEM)
1585 {
1586 if(!(scr->flags4&fNOITEMRESET))
1587 game->maps[mi] &= ~flag;
1588 }
1589 11 else game->maps[mi] &= ~flag;
1590
1591 471 double temp=log2((double)flag);
1592
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1593
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 log_state_change(cmap, cscr, fmt::format("State unset: {}", state_string));
1594
1595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 471 times.
471 if((scr->nocarry&flag)!=flag)
1596 {
1597 471 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1598 471 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1599
1600 471 std::vector<int32_t> done;
1601
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 5 times.
471 bool looped = (nmap==cmap+1 && nscr==cscr);
1602
1603
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 471 times.
555 while((nmap!=0) && !looped && !(nscr>=128))
1604 {
1605
3/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 72 times.
84 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1606 {
1607
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 log_state_change(nmap, nscr, "State change carried over");
1608
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 game->maps[((nmap-1)<<7)+nscr] &= ~flag;
1609 72 }
1610
1611 84 cmap=nmap;
1612 84 cscr=nscr;
1613 84 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1614 84 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1615
1616
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 546 times.
630 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1617 {
1618
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 6 times.
546 if(*it == ((nmap-1)<<7)+nscr)
1619 6 looped = true;
1620 546 }
1621
1622
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 done.push_back(((nmap-1)<<7)+nscr);
1623 }
1624 471 }
1625 471 }
1626
1627 51921377 bool getmapflag(int32_t screen, uint32_t flag)
1628 {
1629
2/2
✓ Branch 0 taken 1345925 times.
✓ Branch 1 taken 50575452 times.
51921377 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1630 51921377 return (game->maps[mi] & flag) != 0;
1631 }
1632 6407106 bool getmapflag(mapscr* scr, uint32_t flag)
1633 {
1634 6407106 return getmapflag(scr->screen, flag);
1635 }
1636
1637 57 void setxmapflag(int32_t screen, uint32_t flag)
1638 {
1639
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1640 57 setxmapflag_mi(mi, flag);
1641 57 }
1642 59 void setxmapflag_mi(int32_t mi, uint32_t flag)
1643 {
1644
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if(game->xstates[mi] & flag) return;
1645 59 byte cscr = mi&((1<<7)-1);
1646 59 byte cmap = (mi>>7);
1647
1648 59 byte temp=(byte)log2((double)flag);
1649
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
59 log_state_change(cmap, cscr, fmt::format("ExtraState set: {}", temp));
1650
1651 59 game->xstates[mi] |= flag;
1652
1653 59 mapscr* scr = origin_scr;
1654
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if (is_in_current_region(cmap, cscr))
1655 59 scr = get_scr(cmap, cscr);
1656
1657
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
59 if((scr->exstate_carry&flag)==flag)
1658 {
1659 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1660 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1661
1662 std::vector<int32_t> done;
1663 bool looped = (nmap==cmap+1 && nscr==cscr);
1664
1665 while((nmap!=0) && !looped && !(nscr>=128))
1666 {
1667 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1668 {
1669 log_state_change(nmap, nscr, "ExState change carried over");
1670 if (replay_is_active())
1671 replay_step_comment(fmt::format("map {} scr {} exstate {} carry", nmap, nscr, temp));
1672 game->xstates[((nmap-1)<<7)+nscr] |= flag;
1673 }
1674
1675 cmap=nmap;
1676 cscr=nscr;
1677 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1678 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1679
1680 for(auto it = done.begin(); it != done.end(); it++)
1681 {
1682 if(*it == ((nmap-1)<<7)+nscr)
1683 looped = true;
1684 }
1685
1686 done.push_back(((nmap-1)<<7)+nscr);
1687 }
1688 }
1689 59 }
1690 2 void unsetxmapflag(int32_t screen, uint32_t flag)
1691 {
1692
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1693 2 unsetxmapflag_mi(mi, flag);
1694 2 }
1695 2 void unsetxmapflag_mi(int32_t mi, uint32_t flag)
1696 {
1697
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(!(game->xstates[mi] & flag)) return;
1698 1 byte cscr = mi&((1<<7)-1);
1699 1 byte cmap = (mi>>7);
1700 1 byte temp=(byte)log2((double)flag);
1701
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 log_state_change(cmap, cscr, fmt::format("ExtraState unset: {}", temp));
1702 1 game->xstates[mi] &= ~flag;
1703
1704 1 mapscr* scr = origin_scr;
1705
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (is_in_current_region(cmap, cscr))
1706 1 scr = get_scr(cmap, cscr);
1707
1708
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if((scr->exstate_carry&flag)==flag)
1709 {
1710 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1711 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1712
1713 std::vector<int32_t> done;
1714 bool looped = (nmap==cmap+1 && nscr==cscr);
1715
1716 while((nmap!=0) && !looped && !(nscr>=128))
1717 {
1718 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1719 {
1720 log_state_change(nmap, nscr, "ExState change carried over");
1721 game->xstates[((nmap-1)<<7)+nscr] &= ~flag;
1722 }
1723
1724 cmap=nmap;
1725 cscr=nscr;
1726 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1727 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1728
1729 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1730 {
1731 if(*it == ((nmap-1)<<7)+nscr)
1732 looped = true;
1733 }
1734
1735 done.push_back(((nmap-1)<<7)+nscr);
1736 }
1737 }
1738 2 }
1739 82 bool getxmapflag(int32_t screen, uint32_t flag)
1740 {
1741
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 82 times.
82 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1742 82 return getxmapflag_mi(mi, flag);
1743 }
1744 488302720 bool getxmapflag_mi(int32_t mi, uint32_t flag)
1745 {
1746 488302720 return (game->xstates[mi] & flag) != 0;
1747 }
1748
1749 4 void setxdoor_mi(uint mi, uint dir, uint ind, bool state)
1750 {
1751
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if(mi > game->xdoors.size() || dir > 3 || ind > 8)
1752 return;
1753
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!(game->xdoors[mi][dir] & (1<<ind)) == !state)
1754 return;
1755
1756
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 SETFLAG(game->xdoors[mi][dir], 1<<ind, state);
1757
1758 4 int cscr = mi % MAPSCRSNORMAL;
1759 4 int cmap = mi / MAPSCRSNORMAL;
1760
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (state)
1761
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] set", dirstr[dir], ind));
1762 else
1763 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] unset", dirstr[dir], ind));
1764 4 }
1765 488302633 bool getxdoor_mi(uint mi, uint dir, uint ind)
1766 {
1767
3/6
✓ Branch 0 taken 488302633 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 488302633 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 488302633 times.
488302633 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1768 return false;
1769 488302633 return (game->xdoors[mi][dir] & (1<<ind));
1770 488302633 }
1771 9 bool getxdoor(int32_t screen, uint dir, uint ind)
1772 {
1773 9 int mi = mapind(cur_map, screen);
1774 9 return getxdoor_mi(mi,dir,ind);
1775 }
1776
1777 401 void set_doorstate_mi(uint mi, uint dir)
1778 {
1779
1/2
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
401 if(dir >= 4)
1780 return;
1781 401 setmapflag_mi(mi, mDOOR_UP << dir);
1782
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if(auto di = nextscr_mi(mi, dir))
1783 400 setmapflag_mi(*di, mDOOR_UP << oppositeDir[dir]);
1784 401 }
1785 401 void set_doorstate(uint screen, uint dir)
1786 {
1787 401 int mi = mapind(cur_map, screen);
1788 401 set_doorstate_mi(mi, dir);
1789 401 }
1790
1791 2 void set_xdoorstate_mi(uint mi, uint dir, uint ind, bool state)
1792 {
1793
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1794 return;
1795 2 setxdoor_mi(mi, dir, ind, state);
1796
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(auto di = nextscr_mi(mi, dir))
1797 2 setxdoor_mi(*di, oppositeDir[dir], ind, state);
1798 2 }
1799
1800 2 void set_xdoorstate(int32_t screen,uint dir, uint ind, bool state)
1801 {
1802 2 int mi = mapind(cur_map, screen);
1803 2 set_xdoorstate_mi(mi, dir, ind, state);
1804 2 }
1805
1806 57 int32_t WARPCODE(int32_t dmap,int32_t screen,int32_t dw)
1807 // returns: -1 = not a warp screen
1808 // 0+ = warp screen code ( high byte=dmap, low byte=scr )
1809 {
1810 57 const mapscr *scr = get_canonical_scr(DMaps[dmap].map, screen);
1811
1812
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(scr->room!=rWARP)
1813 return -1;
1814
1815 57 int32_t ring=scr->catchall;
1816 57 int32_t size=QMisc.warp[ring].size;
1817
1818
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if(size==0)
1819 return -2;
1820
1821 57 int32_t index=-1;
1822
1823
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 57 times.
346 for(int32_t i=0; i<size; i++)
1824
6/6
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 173 times.
✓ Branch 5 taken 57 times.
289 if(dmap==QMisc.warp[ring].dmap[i] && screen==
1825 346 (QMisc.warp[ring].scr[i] + DMaps[dmap].xoff))
1826 57 index=i;
1827
1828
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(index==-1)
1829 return -3;
1830
1831 57 index = (index+dw)%size;
1832 57 return (QMisc.warp[ring].dmap[index] << 8) + QMisc.warp[ring].scr[index];
1833 57 }
1834
1835 15353632 void update_combo_cycling()
1836 {
1837 15353632 auto& combo_cache = combo_caches::can_cycle;
1838
1839 static int32_t newdata[176];
1840 static int32_t newcset[176];
1841 static bool initialized=false;
1842
1843 // Just a simple bit of optimization
1844
2/2
✓ Branch 0 taken 15353314 times.
✓ Branch 1 taken 318 times.
15353632 if(!initialized)
1845 {
1846
2/2
✓ Branch 0 taken 55968 times.
✓ Branch 1 taken 318 times.
56286 for(int32_t i=0; i<176; i++)
1847 {
1848 55968 newdata[i]=-1;
1849 55968 newcset[i]=-1;
1850 55968 }
1851
1852 318 initialized=true;
1853 318 }
1854
1855 15353632 std::set<uint16_t> restartanim;
1856
1857
1/2
✓ Branch 0 taken 15353632 times.
✗ Branch 1 not taken.
31096632 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
1858 15743000 int screen = scr->screen;
1859 int32_t x;
1860
1861
2/2
✓ Branch 0 taken 2770768000 times.
✓ Branch 1 taken 15743000 times.
2786511000 for(int32_t i=0; i<176; i++)
1862 {
1863 2770768000 x=scr->data[i];
1864 2770768000 auto& mini_cmb = combo_cache.minis[x];
1865
2/2
✓ Branch 0 taken 3282224 times.
✓ Branch 1 taken 2767485776 times.
2770768000 if (!mini_cmb.can_cycle)
1866 2767485776 continue;
1867
1868 3282224 newcombo const& cmb = combobuf[x];
1869
1870 //time to restart
1871
4/4
✓ Branch 0 taken 904477 times.
✓ Branch 1 taken 2377747 times.
✓ Branch 2 taken 475770 times.
✓ Branch 3 taken 428707 times.
3282224 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1872 {
1873 428707 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1874
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428707 times.
428707 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1875 428707 newdata[i] = c;
1876
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428687 times.
428707 if(!(cmb.animflags & AF_CYCLENOCSET))
1877
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428687 times.
428687 newcset[i] = cycle_under ? scr->undercset : cmb.nextcset;
1878
1879
2/2
✓ Branch 0 taken 427663 times.
✓ Branch 1 taken 1044 times.
428707 if(combobuf[c].animflags & AF_CYCLE)
1880 {
1881 1044 restartanim.insert(c);
1882 1044 }
1883 428707 }
1884 3282224 }
1885
1886 15743000 int rpos_base = (int)POS_TO_RPOS(0, region_scr_x, region_scr_y);
1887
2/2
✓ Branch 0 taken 2770768000 times.
✓ Branch 1 taken 15743000 times.
2786511000 for(int32_t i=0; i<176; i++)
1888 {
1889
2/2
✓ Branch 0 taken 428707 times.
✓ Branch 1 taken 2770339293 times.
2770768000 if(newdata[i]==-1)
1890 2770339293 continue;
1891
1892 428707 rpos_t rpos = (rpos_t)(rpos_base + i);
1893 428707 rpos_handle_t rpos_handle = {scr, screen, 0, rpos, i};
1894 428707 screen_combo_modify_preroutine(rpos_handle);
1895 428707 scr->data[i]=newdata[i];
1896
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428687 times.
428707 if(newcset[i]>-1)
1897 428687 scr->cset[i]=newcset[i];
1898 428707 screen_combo_modify_postroutine(rpos_handle);
1899
1900 428707 newdata[i]=-1;
1901 428707 newcset[i]=-1;
1902 428707 }
1903
1904 15743000 word c = scr->numFFC();
1905
2/2
✓ Branch 0 taken 15743000 times.
✓ Branch 1 taken 454715631 times.
470458631 for(word i=0; i<c; i++)
1906 {
1907 454715631 ffcdata& ffc = scr->ffcs[i];
1908 454715631 auto& mini_cmb = combo_cache.minis[ffc.data];
1909
2/2
✓ Branch 0 taken 7727 times.
✓ Branch 1 taken 454707904 times.
454715631 if (!mini_cmb.can_cycle)
1910 454707904 continue;
1911
1912 7727 newcombo const& cmb = combobuf[ffc.data];
1913
1914 //time to restart
1915
4/4
✓ Branch 0 taken 1181 times.
✓ Branch 1 taken 6546 times.
✓ Branch 2 taken 856 times.
✓ Branch 3 taken 325 times.
7727 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1916 {
1917 325 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1918
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
325 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1919 325 zc_ffc_set(ffc, c);
1920
2/2
✓ Branch 0 taken 217 times.
✓ Branch 1 taken 108 times.
325 if(!(cmb.animflags & AF_CYCLENOCSET))
1921
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 ffc.cset = cycle_under ? scr->undercset : cmb.nextcset;
1922
1923
2/2
✓ Branch 0 taken 265 times.
✓ Branch 1 taken 60 times.
325 if(combobuf[ffc.data].animflags & AF_CYCLE)
1924 {
1925 60 restartanim.insert(ffc.data);
1926 60 }
1927 325 }
1928 7727 }
1929
1930
2/2
✓ Branch 0 taken 8418399 times.
✓ Branch 1 taken 7324601 times.
15743000 if(get_qr(qr_CMBCYCLELAYERS))
1931 {
1932
2/2
✓ Branch 0 taken 43947606 times.
✓ Branch 1 taken 7324601 times.
51272207 for(int32_t j=1; j<=6; j++)
1933 {
1934 43947606 mapscr* layer_scr = get_scr_layer_valid(screen, j);
1935
2/2
✓ Branch 0 taken 13893876 times.
✓ Branch 1 taken 30053730 times.
43947606 if (!layer_scr)
1936 30053730 continue;
1937
1938
2/2
✓ Branch 0 taken 2445322176 times.
✓ Branch 1 taken 13893876 times.
2459216052 for(int32_t i=0; i<176; i++)
1939 {
1940 2445322176 x=layer_scr->data[i];
1941 2445322176 auto& mini_cmb = combo_cache.minis[x];
1942
2/2
✓ Branch 0 taken 2424344 times.
✓ Branch 1 taken 2442897832 times.
2445322176 if (!mini_cmb.can_cycle)
1943 2442897832 continue;
1944
1945 2424344 newcombo const& cmb = combobuf[x];
1946
1947 //time to restart
1948
4/4
✓ Branch 0 taken 67298 times.
✓ Branch 1 taken 2357046 times.
✓ Branch 2 taken 50626 times.
✓ Branch 3 taken 16672 times.
2424344 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1949 {
1950 16672 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1951
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16672 times.
16672 auto c = cycle_under ? layer_scr->undercombo : cmb.nextcombo;
1952 16672 newdata[i] = c;
1953
2/2
✓ Branch 0 taken 644 times.
✓ Branch 1 taken 16028 times.
16672 if(!(cmb.animflags & AF_CYCLENOCSET))
1954
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16028 times.
16028 newcset[i] = cycle_under ? layer_scr->undercset : cmb.nextcset;
1955 644 else newcset[i] = layer_scr->cset[i];
1956
1957
2/2
✓ Branch 0 taken 6689 times.
✓ Branch 1 taken 9983 times.
16672 if(combobuf[c].animflags & AF_CYCLE)
1958 {
1959 9983 restartanim.insert(c);
1960 9983 }
1961 16672 }
1962 2424344 }
1963
1964
2/2
✓ Branch 0 taken 2445322176 times.
✓ Branch 1 taken 13893876 times.
2459216052 for (int32_t i=0; i<176; i++)
1965 {
1966
2/2
✓ Branch 0 taken 2445305504 times.
✓ Branch 1 taken 16672 times.
2445322176 if(newdata[i]!=-1)
1967 {
1968 16672 layer_scr->data[i]=newdata[i];
1969
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16672 times.
16672 if(newcset[i]>-1)
1970 16672 layer_scr->cset[i]=newcset[i];
1971 16672 newdata[i]=-1;
1972 16672 newcset[i]=-1;
1973 16672 }
1974 2445322176 }
1975 13893876 }
1976 7324601 }
1977 15743000 });
1978
1979
2/2
✓ Branch 0 taken 15353632 times.
✓ Branch 1 taken 2661 times.
15356293 for (auto i : restartanim)
1980 {
1981 2661 combobuf[i].tile = combobuf[i].o_tile;
1982 2661 combobuf[i].cur_frame=0;
1983 2661 combobuf[i].aclk = 0;
1984
1/2
✓ Branch 0 taken 2661 times.
✗ Branch 1 not taken.
2661 combo_caches::drawing.refresh(i);
1985 }
1986 15353632 }
1987
1988 1425575663 bool iswater_type(int32_t type)
1989 {
1990 // return type==cOLD_WATER || type==cSWIMWARP || type==cDIVEWARP || type==cDIVEWARPB || type==cDIVEWARPC || type==cDIVEWARPD || type==cSWIMWARPB || type==cSWIMWARPC || type==cSWIMWARPD;
1991 1425575663 return (combo_class_buf[type].water!=0);
1992 }
1993
1994 bool iswater(int32_t combo)
1995 {
1996 return iswater_type(combobuf[combo].type) && !DRIEDLAKE;
1997 }
1998 5280776 int32_t iswaterexzq(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck)
1999 {
2000 5280776 return iswaterex(combo, map, screen, layer, x, y, secrets, fullcheck, LayerCheck);
2001 }
2002
2003 // (x, y) are world coordinates
2004 68197139 int32_t iswaterex_z3(int32_t combo, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
2005 {
2006
8/8
✓ Branch 0 taken 68149276 times.
✓ Branch 1 taken 47863 times.
✓ Branch 2 taken 68107416 times.
✓ Branch 3 taken 41860 times.
✓ Branch 4 taken 68037933 times.
✓ Branch 5 taken 69483 times.
✓ Branch 6 taken 63405 times.
✓ Branch 7 taken 67974528 times.
68197139 if (x<0 || x>=world_w || y<0 || y>=world_h)
2007 222611 return false;
2008
2009 67974528 return iswaterex(combo, cur_map, cur_screen, layer, x, y, secrets, fullcheck, LayerCheck, ShallowCheck, hero, out_handle);
2010 68197139 }
2011
2012 148527866 int32_t iswaterex(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
2013 {
2014 DCHECK_LAYER_NEG1_INDEX(layer);
2015 //Honestly, fullcheck is kinda useless... I made this function back when I thought it was checking the entire combo and not just a glorified x/y value.
2016 //Fullcheck makes no sense to ever be on, but hey I guess it's here in case you ever need it...
2017
2018 //Oh hey, Zoras might actually need it. Nevermind, this had a use!
2019
2/2
✓ Branch 0 taken 108614493 times.
✓ Branch 1 taken 39913373 times.
148527866 if (get_qr(qr_SMARTER_WATER))
2020 {
2021
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 108614493 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
108614493 if (DRIEDLAKE) return 0;
2022
5/6
✓ Branch 0 taken 32407282 times.
✓ Branch 1 taken 76207211 times.
✓ Branch 2 taken 6533834 times.
✓ Branch 3 taken 25873448 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6533834 times.
108614493 if (LayerCheck && (get_qr(qr_WATER_ON_LAYER_1) || get_qr(qr_WATER_ON_LAYER_2))) //LayerCheck is a bit dumber, but it lets me add this QR without having to replace all calls, again.
2023 {
2024
2/2
✓ Branch 0 taken 75448752 times.
✓ Branch 1 taken 24783435 times.
100232187 for (int32_t m = layer; m <= 1; m++)
2025 {
2026
5/6
✓ Branch 0 taken 49575304 times.
✓ Branch 1 taken 25873448 times.
✓ Branch 2 taken 24790650 times.
✓ Branch 3 taken 24784654 times.
✓ Branch 4 taken 24784654 times.
✗ Branch 5 not taken.
100233406 if (m < 0 || m == 0 && get_qr(qr_WATER_ON_LAYER_1)
2027
1/2
✓ Branch 0 taken 24784654 times.
✗ Branch 1 not taken.
49575304 || m == 1 && get_qr(qr_WATER_ON_LAYER_2))
2028 {
2029 75448752 int32_t checkwater = iswaterex(combo, map, screen, m, x, y, secrets, fullcheck, false, ShallowCheck);
2030
2/2
✓ Branch 0 taken 74358739 times.
✓ Branch 1 taken 1090013 times.
75448752 if (checkwater > 0)
2031 {
2032
2/2
✓ Branch 0 taken 1089930 times.
✓ Branch 1 taken 83 times.
1090013 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, m+1);
2033 1090013 return checkwater;
2034 }
2035 74358739 }
2036 74358739 }
2037 24783435 return 0;
2038 }
2039 else
2040 {
2041
2/2
✓ Branch 0 taken 82764689 times.
✓ Branch 1 taken 78213272 times.
160977961 for(int32_t i=(fullcheck?3:0); i>=0; i--)
2042 {
2043 82764689 int32_t tx2=((i&2)<<2)+x;
2044 82764689 int32_t ty2=((i&1)<<3)+y;
2045 82764689 int32_t b = i; //Originally b was not needed and I read off i, but then I added the boolean for fullcheck.
2046 //In which case it's just easier to change b if fullcheck is false instead of changing i and potentially screwing up the for loop.
2047
2/2
✓ Branch 0 taken 36073 times.
✓ Branch 1 taken 82728616 times.
82764689 if (!fullcheck)
2048 {
2049 82728616 tx2 = x;
2050 82728616 ty2 = y;
2051
2/2
✓ Branch 0 taken 45255923 times.
✓ Branch 1 taken 37472693 times.
82728616 if(tx2&8) b+=2;
2052
2/2
✓ Branch 0 taken 39265168 times.
✓ Branch 1 taken 43463448 times.
82728616 if(ty2&8) b+=1;
2053 82728616 }
2054
2/2
✓ Branch 0 taken 171500853 times.
✓ Branch 1 taken 80321516 times.
251822369 for (int32_t m = layer; m <= 1; m++)
2055 {
2056 171500853 newcombo const& cmb = combobuf[MAPCOMBO3(map, screen, m,tx2,ty2, true)];
2057
3/6
✓ Branch 0 taken 169313350 times.
✓ Branch 1 taken 2187503 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 169313350 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
171500853 if (hero && cmb.dive_under_level && (Hero.get_standing_z_state() <= -cmb.dive_under_level))
2058 continue; // dive under this layer
2059
2060
2/2
✓ Branch 0 taken 17728431 times.
✓ Branch 1 taken 153772422 times.
171500853 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2061 {
2062
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17728431 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17728431 if (cmb.type == cBRIDGE && !(cmb.walk&(1<<b)))
2063 {
2064 return 0;
2065 }
2066 17728431 }
2067 else
2068 {
2069
4/4
✓ Branch 0 taken 253102 times.
✓ Branch 1 taken 153519320 times.
✓ Branch 2 taken 51152 times.
✓ Branch 3 taken 201950 times.
153772422 if (cmb.type == cBRIDGE && (cmb.walk&(0x10<<b)))
2070 {
2071 201950 return 0;
2072 }
2073 }
2074
2/2
✓ Branch 0 taken 17728431 times.
✓ Branch 1 taken 153570472 times.
171298903 if (get_qr(qr_NO_SOLID_SWIM))
2075 {
2076
8/14
✓ Branch 0 taken 51152 times.
✓ Branch 1 taken 153519320 times.
✓ Branch 2 taken 51152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2241223 times.
✓ Branch 5 taken 151278097 times.
✓ Branch 6 taken 34499 times.
✓ Branch 7 taken 2206724 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 34499 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
153570472 if ((cmb.type != cBRIDGE || (!get_qr(qr_OLD_BRIDGE_COMBOS) && !(cmb.walk&(0x10<<b)))) && (cmb.walk&(1<<b)) && !((cmb.usrflags&cflag4) && cmb.type == cWATER && (cmb.walk&(0x10<<b)) && ShallowCheck))
2077 2241223 return 0;
2078 151329249 }
2079
3/6
✓ Branch 0 taken 497938 times.
✓ Branch 1 taken 168559742 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 497938 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
169057680 if (iswater_type(cmb.type) && (cmb.walk&(1<<b)) && ((cmb.usrflags&cflag3) || (cmb.usrflags&cflag4)
2080 || (hero && current_item(itype_flippers) < cmb.attribytes[0])
2081 || (hero && ((cmb.usrflags&cflag1) && !(itemsbuf[current_item_id(itype_flippers)].flags & item_flag3)))))
2082 {
2083 if (!(ShallowCheck && (cmb.walk&(1<<b)) && (cmb.usrflags&cflag4))) return 0;
2084 }
2085 169057680 }
2086
2087 223084245 auto found_ffc_not_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2088
2/2
✓ Branch 0 taken 141975938 times.
✓ Branch 1 taken 786791 times.
142762729 if (ffcIsAt(ffc_handle, tx2, ty2))
2089 {
2090 786791 auto ty = ffc_handle.ctype();
2091
4/6
✓ Branch 0 taken 786791 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193850 times.
✓ Branch 3 taken 592941 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 193850 times.
786791 if(!combo_class_buf[ty].water && !(ShallowCheck && ty == cSHALLOWWATER))
2092 786791 return true;
2093 }
2094
2095 141975938 return false;
2096 142762729 });
2097
2/2
✓ Branch 0 taken 79534725 times.
✓ Branch 1 taken 786791 times.
80321516 if (found_ffc_not_water) return 0;
2098
2099
2/2
✓ Branch 0 taken 23644 times.
✓ Branch 1 taken 79511081 times.
79534725 if(!i)
2100 {
2101 218975805 auto found_ffc_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2102
1/2
✓ Branch 0 taken 139464724 times.
✗ Branch 1 not taken.
139464724 if (ffcIsAt(ffc_handle, tx2, ty2))
2103 {
2104 auto ty = ffc_handle.ctype();
2105 if(combo_class_buf[ty].water || (ShallowCheck && ty == cSHALLOWWATER))
2106 return true;
2107 }
2108
2109 139464724 return false;
2110 139464724 });
2111
1/2
✓ Branch 0 taken 79511081 times.
✗ Branch 1 not taken.
79511081 if (found_ffc_water)
2112 {
2113 if(out_handle) *out_handle = *found_ffc_water;
2114 return found_ffc_water->data();
2115 }
2116 79511081 }
2117
2118 79534725 int32_t checkcombo = MAPCOMBO3(map, screen, layer, tx2, ty2, secrets);
2119
2/2
✓ Branch 0 taken 79490231 times.
✓ Branch 1 taken 44494 times.
79534725 if (!(combobuf[checkcombo].walk&(1<<(b+4)))) return 0;
2120
7/12
✓ Branch 0 taken 79060209 times.
✓ Branch 1 taken 430022 times.
✓ Branch 2 taken 16970924 times.
✓ Branch 3 taken 62089285 times.
✓ Branch 4 taken 16146054 times.
✓ Branch 5 taken 824870 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16146054 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
79490231 if (iswater_type(combobuf[checkcombo].type)||(ShallowCheck && (combobuf[checkcombo].type == cSHALLOWWATER || (iswater_type(combobuf[checkcombo].type) && (combobuf[checkcombo].walk&(1<<b)) && (combobuf[checkcombo].usrflags&cflag4)))))
2121 {
2122
2/2
✓ Branch 0 taken 1577 times.
✓ Branch 1 taken 1253315 times.
1254892 if (i == 0)
2123 {
2124
2/2
✓ Branch 0 taken 1253306 times.
✓ Branch 1 taken 9 times.
1253315 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(tx2, ty2, layer+1);
2125 1253315 return checkcombo;
2126 }
2127 1577 }
2128 78236916 }
2129 78213272 return 0;
2130 }
2131 }
2132 else
2133 {
2134 39913373 int32_t b = 0;
2135
2/2
✓ Branch 0 taken 20700324 times.
✓ Branch 1 taken 19213049 times.
39913373 if(x&8) b+=2;
2136
2/2
✓ Branch 0 taken 15520397 times.
✓ Branch 1 taken 24392976 times.
39913373 if(y&8) b+=1;
2137
1/2
✓ Branch 0 taken 39913373 times.
✗ Branch 1 not taken.
39913373 if (get_qr(qr_NO_SOLID_SWIM))
2138 {
2139 if (combobuf[combo].walk&(1<<b))
2140 {
2141 return 0;
2142 }
2143 }
2144
1/2
✓ Branch 0 taken 39913373 times.
✗ Branch 1 not taken.
39913373 if (!(combobuf[combo].walk&(1<<(b+4)))) return 0;
2145
8/8
✓ Branch 0 taken 38150901 times.
✓ Branch 1 taken 1762472 times.
✓ Branch 2 taken 167945 times.
✓ Branch 3 taken 37982956 times.
✓ Branch 4 taken 2129 times.
✓ Branch 5 taken 1778552 times.
✓ Branch 6 taken 163774 times.
✓ Branch 7 taken 165477 times.
39913373 if((iswater_type(combobuf[combo].type) || (ShallowCheck && combobuf[combo].type == cSHALLOWWATER)) && !DRIEDLAKE)
2146 {
2147
2/2
✓ Branch 0 taken 1943999 times.
✓ Branch 1 taken 30 times.
1944029 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, 0); //NOTE: This is only correct assuming 'combo' is 'MAPCOMBO(x,y)'
2148 1944029 return combo;
2149 }
2150 38146730 return 0;
2151 }
2152 148705252 }
2153
2154 354 bool isdamage_type(int32_t type)
2155 {
2156
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 28 times.
354 switch(type)
2157 {
2158 case cDAMAGE1: case cDAMAGE2: case cDAMAGE3: case cDAMAGE4:
2159 case cDAMAGE5: case cDAMAGE6: case cDAMAGE7:
2160 28 return true;
2161 }
2162 326 return false;
2163 354 }
2164
2165 2230346674 bool ispitfall_type(int32_t type)
2166 {
2167 2230346674 return combo_class_buf[type].pit != 0;
2168 }
2169
2170 2230346674 bool ispitfall(int32_t combo)
2171 {
2172 2230346674 return ispitfall_type(combobuf[combo].type);
2173 }
2174
2175 138842441 bool ispitfall(int32_t x, int32_t y)
2176 {
2177
2/2
✓ Branch 0 taken 1303540 times.
✓ Branch 1 taken 137538901 times.
138842441 if(int32_t c = MAPFFCOMBO(x,y))
2178 {
2179 1303540 return ispitfall(c) ? true : false;
2180 }
2181 137538901 int32_t c = MAPCOMBOL(2,x,y);
2182
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 137538824 times.
137538901 if(ispitfall(c)) return true;
2183
2/2
✓ Branch 0 taken 122656443 times.
✓ Branch 1 taken 14882381 times.
137538824 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2184 {
2185
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 122656443 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
122656443 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return false;
2186 122656443 }
2187 else
2188 {
2189
3/4
✓ Branch 0 taken 16383 times.
✓ Branch 1 taken 14865998 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16383 times.
14882381 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return false;
2190 }
2191 137522441 c = MAPCOMBOL(1,x,y);
2192
2/2
✓ Branch 0 taken 19968 times.
✓ Branch 1 taken 137502473 times.
137522441 if(ispitfall(c)) return true;
2193
2194
2/2
✓ Branch 0 taken 122656443 times.
✓ Branch 1 taken 14846030 times.
137502473 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2195 {
2196
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 122656443 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
122656443 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return false;
2197 122656443 }
2198 else
2199 {
2200
4/4
✓ Branch 0 taken 16533 times.
✓ Branch 1 taken 14829497 times.
✓ Branch 2 taken 12238 times.
✓ Branch 3 taken 4295 times.
14846030 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return false;
2201 }
2202 137490235 c = MAPCOMBO(x,y);
2203
2/2
✓ Branch 0 taken 59028 times.
✓ Branch 1 taken 137431207 times.
137490235 if(ispitfall(c)) return true;
2204 137431207 return false;
2205 138842441 }
2206
2207 611927937 int32_t getpitfall(int32_t x, int32_t y) //Return the highest-layer active pit combo at the given position
2208 {
2209
2/2
✓ Branch 0 taken 9485176 times.
✓ Branch 1 taken 602442761 times.
611927937 if(int32_t c = MAPFFCOMBO(x,y))
2210 {
2211
2/2
✓ Branch 0 taken 845 times.
✓ Branch 1 taken 9484331 times.
9485176 return ispitfall(c) ? c : 0;
2212 }
2213 602442761 int32_t c = MAPCOMBOL(2,x,y);
2214
2/2
✓ Branch 0 taken 1362 times.
✓ Branch 1 taken 602441399 times.
602442761 if(ispitfall(c)) return c;
2215
2216
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 69718914 times.
602441399 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2217 {
2218
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return 0;
2219 532722485 }
2220 else
2221 {
2222
3/4
✓ Branch 0 taken 81755 times.
✓ Branch 1 taken 69637159 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 81755 times.
69718914 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return 0;
2223 }
2224 602359644 c = MAPCOMBOL(1,x,y);
2225
2/2
✓ Branch 0 taken 25192 times.
✓ Branch 1 taken 602334452 times.
602359644 if(ispitfall(c)) return c;
2226
2227
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 69611967 times.
602334452 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2228 {
2229
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return 0;
2230 532722485 }
2231 else
2232 {
2233
4/4
✓ Branch 0 taken 171385 times.
✓ Branch 1 taken 69440582 times.
✓ Branch 2 taken 130757 times.
✓ Branch 3 taken 40628 times.
69611967 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return 0;
2234 }
2235 602203695 c = MAPCOMBO(x,y);
2236
2/2
✓ Branch 0 taken 200737 times.
✓ Branch 1 taken 602002958 times.
602203695 if(ispitfall(c)) return c;
2237 602002958 return 0;
2238 611927937 }
2239 99 optional<combined_handle_t> get_pitfall_handle(int32_t x, int32_t y) //Return the highest-layer active pit combo handle at the given position
2240 {
2241
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 98 times.
99 if(int32_t c = MAPFFCOMBO(x,y))
2242 {
2243
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 return ispitfall(c) ? getFFCAt(x,y) : nullopt;
2244 }
2245 98 int32_t c = MAPCOMBOL(2,x,y);
2246
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 97 times.
98 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 2);
2247
2248
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 91 times.
97 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2249 {
2250
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1))
2251 return nullopt;
2252 6 }
2253 else
2254 {
2255
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
91 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1))
2256 return nullopt;
2257 }
2258 97 c = MAPCOMBOL(1,x,y);
2259
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 85 times.
97 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 1);
2260
2261
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 79 times.
85 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2262 {
2263
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0))
2264 return nullopt;
2265 6 }
2266 else
2267 {
2268
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 79 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
79 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0))
2269 return nullopt;
2270 }
2271 85 c = MAPCOMBO(x,y);
2272
1/2
✓ Branch 0 taken 85 times.
✗ Branch 1 not taken.
85 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 0);
2273 return nullopt;
2274 99 }
2275 11915697 bool check_icy(newcombo const& cmb, int type)
2276 {
2277
2/2
✓ Branch 0 taken 11915532 times.
✓ Branch 1 taken 165 times.
11915697 if(cmb.type != cICY)
2278 11915532 return false;
2279
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 165 times.
165 switch(type)
2280 {
2281 case ICY_BLOCK:
2282 return cmb.usrflags&cflag1;
2283 case ICY_PLAYER:
2284 165 return cmb.usrflags&cflag2;
2285 }
2286 return false;
2287 11915697 }
2288 3977849 int get_icy(int x, int y, int type)
2289 {
2290 3977849 int32_t c = MAPCOMBOL(2,x,y);
2291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3977849 times.
3977849 if(check_icy(combobuf[c], type)) return c;
2292
2293 3977849 int screen = get_screen_for_world_xy(x, y);
2294
2295 3977849 mapscr* scr = get_scr_layer_valid(screen, 2);
2296
2/2
✓ Branch 0 taken 33063 times.
✓ Branch 1 taken 3944786 times.
3977849 if (scr)
2297 {
2298
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 3944270 times.
3944786 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2299 {
2300
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 516 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
516 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2301 516 }
2302 else
2303 {
2304
3/4
✓ Branch 0 taken 6663 times.
✓ Branch 1 taken 3937607 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6663 times.
3944270 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2305 }
2306 3938123 }
2307 3971186 c = MAPCOMBOL(1,x,y);
2308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3971186 times.
3971186 if(check_icy(combobuf[c], type)) return c;
2309
2310 3971186 scr = get_scr_layer_valid(screen, 1);
2311
2/2
✓ Branch 0 taken 15202 times.
✓ Branch 1 taken 3955984 times.
3971186 if (scr)
2312 {
2313
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 3954050 times.
3955984 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2314 {
2315
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1934 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1934 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2316 1934 }
2317 else
2318 {
2319
3/4
✓ Branch 0 taken 4689 times.
✓ Branch 1 taken 3949361 times.
✓ Branch 2 taken 4689 times.
✗ Branch 3 not taken.
3954050 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2320 }
2321 3951295 }
2322 3966497 c = MAPCOMBO(x,y);
2323
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3966497 times.
3966497 if(check_icy(combobuf[c], type)) return c;
2324 3966497 return 0;
2325 3977849 }
2326
2327 13247555 static bool checkSV(int32_t x, int32_t y, int32_t flag)
2328 {
2329
8/8
✓ Branch 0 taken 13240757 times.
✓ Branch 1 taken 6798 times.
✓ Branch 2 taken 13231891 times.
✓ Branch 3 taken 8866 times.
✓ Branch 4 taken 13220259 times.
✓ Branch 5 taken 11632 times.
✓ Branch 6 taken 434748 times.
✓ Branch 7 taken 12785511 times.
13247555 if(x<0 || x>=world_w || y<0 || y>=world_h)
2330 462044 return false;
2331
2332 12785511 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
2333
2/4
✓ Branch 0 taken 12785511 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12785511 times.
12785511 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2334 return true;
2335
2336 12785511 change_rpos_handle_layer(rpos_handle, 1);
2337
2/2
✓ Branch 0 taken 7558234 times.
✓ Branch 1 taken 5227277 times.
12785511 if (rpos_handle.scr->is_valid())
2338
3/4
✓ Branch 0 taken 5227277 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3279 times.
✓ Branch 3 taken 5223998 times.
5227277 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2339 3279 return true;
2340
2341 12782232 change_rpos_handle_layer(rpos_handle, 2);
2342
2/2
✓ Branch 0 taken 10842036 times.
✓ Branch 1 taken 1940196 times.
12782232 if (rpos_handle.scr->is_valid())
2343
3/4
✓ Branch 0 taken 1940196 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 1940115 times.
1940196 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2344 81 return true;
2345
2346 12782151 return false;
2347 13247555 }
2348
2349 6687960 bool isSVLadder(int32_t x, int32_t y)
2350 {
2351 6687960 return checkSV(x, y, mfSIDEVIEWLADDER);
2352 }
2353
2354 6559595 bool isSVPlatform(int32_t x, int32_t y)
2355 {
2356 6559595 return checkSV(x, y, mfSIDEVIEWPLATFORM);
2357 }
2358
2359 6559595 bool checkSVLadderPlatform(int32_t x, int32_t y)
2360 {
2361
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6559595 times.
✓ Branch 2 taken 6557757 times.
✓ Branch 3 taken 1838 times.
6559595 return isSVPlatform(x,y) || (isSVLadder(x,y) && !isSVLadder(x,y-16));
2362 }
2363
2364 4206 bool isstepable(int32_t combo) //can use ladder on it
2365 {
2366
2/2
✓ Branch 0 taken 4200 times.
✓ Branch 1 taken 6 times.
4206 if(combo_class_buf[combobuf[combo].type].ladder_pass) return true;
2367
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(combo_class_buf[combobuf[combo].type].pit)
2368 {
2369 if(combobuf[combo].usrflags&cflag4)
2370 {
2371 int32_t ldrid = current_item_id(itype_ladder);
2372 return (ldrid > -1 && itemsbuf[ldrid].flags & item_flag1);
2373 }
2374 }
2375 6 return false;
2376 4206 }
2377
2378 33016 bool isHSGrabbable(newcombo const& cmb)
2379 {
2380
2/2
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 32639 times.
33016 if(cmb.type == cHSGRAB) return true;
2381 32639 return cmb.genflags & cflag1;
2382 33016 }
2383
2384 954 bool isSwitchHookable(newcombo const& cmb)
2385 {
2386
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 822 times.
954 if(cmb.type == cSWITCHHOOK) return true;
2387 822 return cmb.genflags & cflag2;
2388 954 }
2389
2390 62207 bool check_hshot(int32_t layer, int32_t x, int32_t y, bool switchhook, rpos_t *out_rpos, ffcdata **out_ffc)
2391 {
2392 62207 rpos_t cpos = rpos_t::None;
2393
2/2
✓ Branch 0 taken 65056 times.
✓ Branch 1 taken 127263 times.
62207 if(out_rpos)
2394 {
2395 127263 int32_t id = MAPCOMBO2(layer-1,x,y);
2396
2/2
✓ Branch 0 taken 29204 times.
✓ Branch 1 taken 98059 times.
127263 if(id > 0)
2397 {
2398 98059 newcombo const& cmb = combobuf[id];
2399
4/4
✓ Branch 0 taken 32974 times.
✓ Branch 1 taken 65085 times.
✓ Branch 2 taken 32528 times.
✓ Branch 3 taken 32557 times.
98059 cpos = (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb)) ? COMBOPOS_REGION(x,y) : rpos_t::None;
2400 33003 }
2401 62207 }
2402
2403 127263 ffcdata* ffc = nullptr;
2404
4/4
✓ Branch 0 taken 28531 times.
✓ Branch 1 taken 98732 times.
✓ Branch 2 taken 24996 times.
✓ Branch 3 taken 3535 times.
127263 if (out_ffc && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2405 {
2406 10645 for_some_ffcs([&](const ffc_handle_t& ffc_handle) {
2407
2/2
✓ Branch 0 taken 6995 times.
✓ Branch 1 taken 115 times.
7110 if (ffcIsAt(ffc_handle, x, y))
2408 {
2409 115 auto& cmb = ffc_handle.combo();
2410
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 37 times.
✓ Branch 3 taken 36 times.
115 if (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb))
2411 {
2412 79 ffc = ffc_handle.ffc;
2413 79 return false;
2414 }
2415 36 }
2416 7031 return true;
2417 7038 });
2418 3535 }
2419
2420
4/4
✓ Branch 0 taken 62207 times.
✓ Branch 1 taken 65056 times.
✓ Branch 2 taken 446 times.
✓ Branch 3 taken 61761 times.
127263 if (out_rpos && cpos != rpos_t::None) *out_rpos = cpos;
2421
4/4
✓ Branch 0 taken 28531 times.
✓ Branch 1 taken 98732 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 28524 times.
127263 if (out_ffc && ffc) *out_ffc = ffc;
2422
2/2
✓ Branch 0 taken 65502 times.
✓ Branch 1 taken 61761 times.
127263 return (cpos != rpos_t::None || ffc);
2423 }
2424
2425 5199 bool ishookshottable(int32_t bx, int32_t by)
2426 {
2427
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5199 times.
5199 if(!_walkflag(bx,by,1))
2428 return true;
2429
2430
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5191 times.
5199 if (collide_object(bx, by, 1, 1))
2431 8 return false;
2432
2433 5191 bool ret = true;
2434
2/2
✓ Branch 0 taken 15573 times.
✓ Branch 1 taken 1904 times.
17477 for(int32_t i=2; i>=0; i--)
2435 {
2436 15573 int32_t c = MAPCOMBO2(i-1,bx,by);
2437 15573 int32_t t = combobuf[c].type;
2438
2439
6/6
✓ Branch 0 taken 5191 times.
✓ Branch 1 taken 10382 times.
✓ Branch 2 taken 3857 times.
✓ Branch 3 taken 1334 times.
✓ Branch 4 taken 1904 times.
✓ Branch 5 taken 1953 times.
15573 if(i == 0 && (t == cHOOKSHOTONLY || t == cLADDERHOOKSHOT)) return true;
2440
2441
3/4
✓ Branch 0 taken 11333 times.
✓ Branch 1 taken 953 times.
✓ Branch 2 taken 953 times.
✗ Branch 3 not taken.
13239 bool dried = (iswater_type(t) && DRIEDLAKE);
2442
2443 12286 int32_t b=1;
2444
2445
2/2
✓ Branch 0 taken 6112 times.
✓ Branch 1 taken 6174 times.
12286 if(bx&8) b<<=2;
2446
2447
2/2
✓ Branch 0 taken 3853 times.
✓ Branch 1 taken 8433 times.
12286 if(by&8) b<<=1;
2448
2449
7/8
✓ Branch 0 taken 2098 times.
✓ Branch 1 taken 10188 times.
✓ Branch 2 taken 2098 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1115 times.
✓ Branch 5 taken 983 times.
✓ Branch 6 taken 75 times.
✓ Branch 7 taken 908 times.
12286 if(combobuf[c].walk&b && !dried && !(combo_class_buf[t].ladder_pass && t!=cLADDERONLY) && t!=cHOOKSHOTONLY)
2450 908 ret = false;
2451 12286 }
2452
2453 1904 return ret;
2454 5199 }
2455
2456 11108 bool reveal_hidden_stairs(mapscr *s, int32_t screen, bool redraw)
2457 {
2458
4/4
✓ Branch 0 taken 10529 times.
✓ Branch 1 taken 579 times.
✓ Branch 2 taken 10529 times.
✓ Branch 3 taken 579 times.
11108 if((s->stairx || s->stairy) && s->secretcombo[sSTAIRS])
2459 {
2460 579 int pos = COMBOPOS(s->stairx,s->stairy);
2461 579 s->data[pos] = s->secretcombo[sSTAIRS];
2462 579 s->cset[pos] = s->secretcset[sSTAIRS];
2463 579 s->sflag[pos] = s->secretflag[sSTAIRS];
2464
2465
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 323 times.
579 if (redraw)
2466 {
2467 768 auto [x, y] = translate_screen_coordinates_to_world(screen, s->stairx, s->stairy);
2468 768 putcombo(scrollbuf,x,y,s->data[pos],s->cset[pos]);
2469 256 }
2470
2471 579 return true;
2472 }
2473
2474 10529 return false;
2475 11108 }
2476
2477 52903 screen_handles_t create_screen_handles_one(mapscr* base_scr)
2478 {
2479 DCHECK(base_scr->is_valid());
2480
2481 52903 screen_handles_t screen_handles{};
2482 52903 screen_handles[0] = {base_scr, base_scr, base_scr->screen, 0};
2483 52903 return screen_handles;
2484 }
2485
2486 58555071 screen_handles_t create_screen_handles(mapscr* base_scr)
2487 {
2488 DCHECK(get_scr(base_scr->screen) == base_scr);
2489 DCHECK(base_scr->is_valid());
2490
2491 58555071 int screen = base_scr->screen;
2492 screen_handles_t screen_handles;
2493 58555071 screen_handles[0] = {base_scr, base_scr, screen, 0};
2494
2/2
✓ Branch 0 taken 351330426 times.
✓ Branch 1 taken 58555071 times.
409885497 for (int i = 1; i <= 6; i++)
2495 351330426 screen_handles[i] = {base_scr, get_scr_layer_valid(screen, i), screen, i};
2496 58555071 return screen_handles;
2497 }
2498
2499 113471 bool remove_screenstatecombos2(const screen_handles_t& screen_handles, bool do_layers, int32_t what1, int32_t what2)
2500 {
2501 113471 mapscr* scr = screen_handles[0].scr;
2502 113471 bool didit=false;
2503
2504
2/2
✓ Branch 0 taken 113471 times.
✓ Branch 1 taken 19970896 times.
20084367 for(int32_t i=0; i<176; i++)
2505 {
2506 19970896 newcombo const& cmb = combobuf[scr->data[i]];
2507
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 19970570 times.
19970896 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2508
4/4
✓ Branch 0 taken 19968994 times.
✓ Branch 1 taken 1576 times.
✓ Branch 2 taken 1134 times.
✓ Branch 3 taken 19967860 times.
19970570 if((cmb.type == what1) || (cmb.type== what2))
2509 {
2510 2710 scr->data[i]++;
2511 2710 didit=true;
2512 2710 }
2513 19970570 }
2514
2515
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 113379 times.
113471 if (do_layers)
2516 {
2517
2/2
✓ Branch 0 taken 680274 times.
✓ Branch 1 taken 113379 times.
793653 for(int32_t j=1; j<=6; j++)
2518 {
2519 680274 mapscr* layer_scr = screen_handles[j].scr;
2520
2/2
✓ Branch 0 taken 195881 times.
✓ Branch 1 taken 484393 times.
680274 if (!layer_scr) continue;
2521
2522
2/2
✓ Branch 0 taken 34475056 times.
✓ Branch 1 taken 195881 times.
34670937 for(int32_t i=0; i<176; i++)
2523 {
2524 34475056 newcombo const& cmb = combobuf[layer_scr->data[i]];
2525
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34475056 times.
34475056 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2526
4/4
✓ Branch 0 taken 34474741 times.
✓ Branch 1 taken 315 times.
✓ Branch 2 taken 319 times.
✓ Branch 3 taken 34474422 times.
34475056 if((cmb.type== what1) || (cmb.type== what2))
2527 {
2528 634 layer_scr->data[i]++;
2529 634 didit=true;
2530 634 }
2531 34475056 }
2532 195881 }
2533 113379 }
2534
2535 // 'do_layers' also means that this is called on an active temp screen, so update its ffcs.
2536
3/4
✓ Branch 0 taken 27675 times.
✓ Branch 1 taken 85796 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27675 times.
113471 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && do_layers)
2537 {
2538 27675 word c = scr->numFFC();
2539
2/2
✓ Branch 0 taken 80883 times.
✓ Branch 1 taken 27675 times.
108558 for(word i=0; i<c; i++)
2540 {
2541 80883 ffcdata* ffc = &scr->ffcs[i];
2542 80883 newcombo const& cmb = combobuf[ffc->data];
2543
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80883 times.
80883 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2544
2/4
✓ Branch 0 taken 80883 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 80883 times.
80883 if((cmb.type== what1) || (cmb.type== what2))
2545 {
2546 zc_ffc_modify(*ffc, 1);
2547 didit=true;
2548 }
2549 80883 }
2550 27675 }
2551
2552 113471 return didit;
2553 }
2554
2555 14 bool remove_xstatecombos(const screen_handles_t& screen_handles, byte xflag, bool triggers)
2556 {
2557 14 int screen = screen_handles[0].scr->screen;
2558
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2559 14 return remove_xstatecombos_mi(screen_handles, mi, xflag, triggers);
2560 }
2561 488302638 bool remove_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, byte xflag, bool triggers)
2562 {
2563 488302638 bool didit=false;
2564
2/2
✓ Branch 0 taken 488261677 times.
✓ Branch 1 taken 40961 times.
488302638 if(!getxmapflag_mi(mi, 1<<xflag)) return false;
2565
2566 40961 mapscr* s = screen_handles[0].scr;
2567 40961 int screen = s->screen;
2568 40961 bool is_active_screen = is_in_current_region(s);
2569
2570 34122305 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2571
4/4
✓ Branch 0 taken 49456 times.
✓ Branch 1 taken 34031888 times.
✓ Branch 2 taken 1891 times.
✓ Branch 3 taken 34079453 times.
34081344 if(triggers && force_ex_trigger_any(rpos_handle, xflag))
2572 1891 didit = true;
2573
2/2
✓ Branch 0 taken 64673 times.
✓ Branch 1 taken 34014780 times.
34079453 else switch (rpos_handle.ctype())
2574 {
2575 case cLOCKBLOCK: case cLOCKBLOCK2:
2576 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2577 case cCHEST: case cCHEST2:
2578 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2579 case cBOSSCHEST: case cBOSSCHEST2:
2580 {
2581 64673 auto& cmb = rpos_handle.combo();
2582
2/2
✓ Branch 0 taken 62059 times.
✓ Branch 1 taken 2614 times.
64673 if(!(cmb.usrflags&cflag16)) return; //custom state instead of normal state
2583
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 62030 times.
62059 if(cmb.attribytes[5] == xflag)
2584 {
2585 29 rpos_handle.increment_data();
2586 29 didit=true;
2587 29 }
2588 62059 break;
2589 }
2590 }
2591 34081344 });
2592
2593
4/4
✓ Branch 0 taken 40889 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 31269 times.
✓ Branch 3 taken 9620 times.
40961 if (is_active_screen && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2594 {
2595 31269 word c = s->numFFC();
2596 31269 int screen_index_offset = get_region_screen_offset(screen);
2597
2/2
✓ Branch 0 taken 65746 times.
✓ Branch 1 taken 31269 times.
97015 for (uint8_t i = 0; i < c; i++)
2598 {
2599 65746 auto ffc_handle = *s->getFFCHandle(i, screen_index_offset);
2600 65746 auto& cmb = ffc_handle.combo();
2601
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 65746 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 65730 times.
65746 if(triggers && force_ex_trigger_any(ffc_handle, xflag))
2602 16 didit = true;
2603
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65730 times.
65730 else switch(cmb.type)
2604 {
2605 case cLOCKBLOCK: case cLOCKBLOCK2:
2606 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2607 case cCHEST: case cCHEST2:
2608 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2609 case cBOSSCHEST: case cBOSSCHEST2:
2610 {
2611 if(!(cmb.usrflags&cflag16)) continue; //custom state instead of normal state
2612 if(cmb.attribytes[5] == xflag)
2613 {
2614 zc_ffc_modify(*ffc_handle.ffc, 1);
2615 didit=true;
2616 }
2617 break;
2618 }
2619 }
2620 65746 }
2621 31269 }
2622
2623 40961 return didit;
2624 488302638 }
2625
2626 15206331 void clear_xstatecombos(const screen_handles_t& screen_handles, bool triggers)
2627 {
2628 15206331 int screen = screen_handles[0].screen;
2629
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14818498 times.
15206331 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2630 15206331 clear_xstatecombos_mi(screen_handles, mi, triggers);
2631 15206331 }
2632
2633 15259457 void clear_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2634 {
2635
2/2
✓ Branch 0 taken 488302624 times.
✓ Branch 1 taken 15259457 times.
503562081 for (int q = 0; q < 32; ++q)
2636 {
2637 488302624 remove_xstatecombos_mi(screen_handles, mi, q, triggers);
2638 488302624 }
2639 15259457 }
2640
2641 bool remove_xdoors(const screen_handles_t& screen_handles, uint dir, uint ind, bool triggers)
2642 {
2643 int screen = screen_handles[0].screen;
2644 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2645 return remove_xdoors_mi(screen_handles, mi, dir, ind, triggers);
2646 }
2647 488302624 bool remove_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, uint dir, uint ind, bool triggers)
2648 {
2649 488302624 bool didit=false;
2650
2/2
✓ Branch 0 taken 488301311 times.
✓ Branch 1 taken 1313 times.
488302624 if (!getxdoor_mi(mi, dir, ind)) return false;
2651
2652 1313 mapscr* scr = screen_handles[0].scr;
2653 1313 int screen = scr->screen;
2654 1313 bool is_active_screen = is_in_current_region(scr);
2655
2656 925665 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2657
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 924352 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 924341 times.
924352 if (triggers && force_ex_door_trigger_any(rpos_handle, dir, ind))
2658 11 didit = true;
2659 else; //future door combo types?
2660 924352 });
2661
2662
2/4
✓ Branch 0 taken 1313 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1313 times.
✗ Branch 3 not taken.
1313 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && is_active_screen)
2663 {
2664 1313 word c = scr->numFFC();
2665 1313 int screen_index_offset = get_region_screen_offset(screen);
2666
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1313 times.
1313 for (uint8_t i = 0; i < c; i++)
2667 {
2668 auto ffc_handle = *scr->getFFCHandle(i, screen_index_offset);
2669 if (triggers && force_ex_door_trigger_any(ffc_handle, dir, ind))
2670 didit = true;
2671 else; //future door combo types?
2672 }
2673 1313 }
2674
2675 1313 return didit;
2676 488302624 }
2677
2678 15206331 void clear_xdoors(const screen_handles_t& screen_handles, bool triggers)
2679 {
2680 15206331 int screen = screen_handles[0].screen;
2681
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14818498 times.
15206331 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2682 15206331 return clear_xdoors_mi(screen_handles, mi, triggers);
2683 }
2684
2685 15259457 void clear_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2686 {
2687
2/2
✓ Branch 0 taken 61037828 times.
✓ Branch 1 taken 15259457 times.
76297285 for (int dir = 0; dir < 4; ++dir)
2688
2/2
✓ Branch 0 taken 488302624 times.
✓ Branch 1 taken 61037828 times.
549340452 for (int q = 0; q < 8; ++q)
2689 549340452 remove_xdoors_mi(screen_handles, mi, dir, q, triggers);
2690 15259457 }
2691
2692 885 bool remove_lockblocks(const screen_handles_t& screen_handles)
2693 {
2694 885 return remove_screenstatecombos2(screen_handles, true, cLOCKBLOCK, cLOCKBLOCK2);
2695 }
2696
2697 139 bool remove_bosslockblocks(const screen_handles_t& screen_handles)
2698 {
2699 139 return remove_screenstatecombos2(screen_handles, true, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
2700 }
2701
2702 83659 bool remove_chests(const screen_handles_t& screen_handles)
2703 {
2704 83659 return remove_screenstatecombos2(screen_handles, true, cCHEST, cCHEST2);
2705 }
2706
2707 2484 bool remove_lockedchests(const screen_handles_t& screen_handles)
2708 {
2709 2484 return remove_screenstatecombos2(screen_handles, true, cLOCKEDCHEST, cLOCKEDCHEST2);
2710 }
2711
2712 26212 bool remove_bosschests(const screen_handles_t& screen_handles)
2713 {
2714 26212 return remove_screenstatecombos2(screen_handles, true, cBOSSCHEST, cBOSSCHEST2);
2715 }
2716
2717 1418795 void delete_fireball_shooter(const rpos_handle_t& rpos_handle)
2718 {
2719 1418795 int32_t ct=rpos_handle.ctype();
2720
2721
6/6
✓ Branch 0 taken 1418175 times.
✓ Branch 1 taken 620 times.
✓ Branch 2 taken 1417923 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 1417815 times.
✓ Branch 5 taken 108 times.
1418795 if(ct!=cL_STATUE && ct!=cR_STATUE && ct!=cC_STATUE)
2722 1417815 return;
2723
2724 2465 auto [cx, cy] = rpos_handle.xy();
2725
3/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 620 times.
✓ Branch 3 taken 108 times.
980 switch(ct)
2726 {
2727 case cL_STATUE:
2728 620 cx += 4;
2729 620 cy += 7;
2730 620 break;
2731
2732 case cR_STATUE:
2733 252 cx -= 8;
2734 252 cy -= 1;
2735 252 break;
2736
2737 case cC_STATUE:
2738 108 break;
2739 }
2740
2741
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 1485 times.
2465 for(int32_t j=0; j<guys.Count(); j++)
2742 {
2743 // Finds the smallest enemy ID
2744
9/10
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 1086 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 53 times.
✓ Branch 8 taken 346 times.
✗ Branch 9 not taken.
2970 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy)&&(guysbuf[(guys.spr(j)->id)&0xFFF].flags & guy_fire))
2745 {
2746 346 guys.del(j);
2747 346 }
2748 1485 }
2749 1418795 }
2750
2751 45 static int32_t findtrigger(int32_t screen)
2752 {
2753 45 int32_t checkflag=0;
2754 45 int32_t ret = 0;
2755
2756 mapscr* screens[7];
2757
2/2
✓ Branch 0 taken 315 times.
✓ Branch 1 taken 45 times.
360 for (int32_t j = 0; j <= 6; j++)
2758 {
2759 315 screens[j] = get_scr_layer_valid(screen, j);
2760 315 }
2761
2762 45 bool sflag = false;
2763
2/2
✓ Branch 0 taken 7920 times.
✓ Branch 1 taken 45 times.
7965 for(word j=0; j<176; j++)
2764 {
2765
2/2
✓ Branch 0 taken 87648 times.
✓ Branch 1 taken 7920 times.
95568 for(int32_t layer = -1; layer < 6; ++layer)
2766 {
2767 87648 mapscr* scr = screens[layer+1];
2768
2/2
✓ Branch 0 taken 64416 times.
✓ Branch 1 taken 23232 times.
87648 if (!scr) continue;
2769
2770
2/2
✓ Branch 0 taken 32208 times.
✓ Branch 1 taken 32208 times.
64416 if(sflag)
2771 32208 checkflag = scr->sflag[j];
2772 else
2773 32208 checkflag = combobuf[scr->data[j]].flag;
2774 64416 sflag = !sflag;
2775
2/2
✓ Branch 0 taken 32208 times.
✓ Branch 1 taken 32208 times.
64416 if (sflag) --layer;
2776
2777
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 64374 times.
64416 switch(checkflag)
2778 {
2779 case mfANYFIRE:
2780 case mfSTRONGFIRE:
2781 case mfMAGICFIRE:
2782 case mfDIVINEFIRE:
2783 case mfARROW:
2784 case mfSARROW:
2785 case mfGARROW:
2786 case mfSBOMB:
2787 case mfBOMB:
2788 case mfBRANG:
2789 case mfMBRANG:
2790 case mfFBRANG:
2791 case mfWANDMAGIC:
2792 case mfREFMAGIC:
2793 case mfREFFIREBALL:
2794 case mfSWORD:
2795 case mfWSWORD:
2796 case mfMSWORD:
2797 case mfXSWORD:
2798 case mfSWORDBEAM:
2799 case mfWSWORDBEAM:
2800 case mfMSWORDBEAM:
2801 case mfXSWORDBEAM:
2802 case mfHOOKSHOT:
2803 case mfWAND:
2804 case mfHAMMER:
2805 case mfSTRIKE:
2806 42 ret += 1;
2807 42 break;
2808 }
2809 64416 }
2810 7920 }
2811
2812 45 return ret;
2813 }
2814
2815 12340 static void log_trigger_secret_reason(TriggerSource source)
2816 {
2817
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11888 times.
12340 if (source == TriggerSource::Singular)
2818 {
2819 452 Z_eventlog("Restricted Screen Secrets triggered\n");
2820 452 }
2821 else
2822 {
2823 11888 const char* source_str = "";
2824
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7297 times.
✓ Branch 3 taken 897 times.
✓ Branch 4 taken 3114 times.
✓ Branch 5 taken 500 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 75 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
11888 switch (source)
2825 {
2826 case TriggerSource::Singular: break;
2827 7297 case TriggerSource::Unspecified: source_str = "unspecified means"; break;
2828 897 case TriggerSource::EnemiesScreenFlag: source_str = "the 'Enemies->Secret' screen flag"; break;
2829 3114 case TriggerSource::SecretsScreenState: source_str = "the 'Secrets' screen state"; break;
2830 500 case TriggerSource::Script: source_str = "a script"; break;
2831 1 case TriggerSource::ItemsSecret: source_str = "Items->Secrets"; break;
2832 75 case TriggerSource::GenericCombo: source_str = "Generic Combo"; break;
2833 4 case TriggerSource::LightTrigger: source_str = "Light Triggers"; break;
2834 case TriggerSource::SCC: source_str = "SCC"; break;
2835 case TriggerSource::CheatTemp: source_str = "Cheat (Temp)"; break;
2836 case TriggerSource::CheatPerm: source_str = "Cheat (Perm)"; break;
2837 }
2838 11888 Z_eventlog("Screen Secrets triggered by %s\n", source_str);
2839 }
2840 12340 }
2841
2842 // single:
2843 // >-1 : the singular triggering combo
2844 // -1: triggered by some other cause
2845 12132 void trigger_secrets_for_screen(TriggerSource source, mapscr* scr, bool high16only, int32_t single)
2846 {
2847 12132 log_trigger_secret_reason(source);
2848
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11680 times.
12132 if (single < 0)
2849 11680 get_screen_state(scr->screen).triggered_secrets = true;
2850
2851 12132 bool do_replay_comment = true;
2852 12132 bool from_active_screen = true;
2853 12132 trigger_secrets_for_screen_internal(create_screen_handles(scr), from_active_screen, high16only, single, do_replay_comment);
2854
2855 // Respect secret state carryovers for active screens.
2856
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11680 times.
12132 if (single >= 0) return;
2857
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 11655 times.
11680 if(scr->nocarry&mSECRET) return;
2858 11655 int cmap = scr->map;
2859 11655 int cscr = scr->screen;
2860 11655 int nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
2861 11655 int nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
2862
2863 11655 std::vector<int32_t> done;
2864
2/2
✓ Branch 0 taken 11450 times.
✓ Branch 1 taken 205 times.
11655 bool looped = (nmap==cmap+1 && nscr==cscr);
2865
2866
6/6
✓ Branch 0 taken 586 times.
✓ Branch 1 taken 11569 times.
✓ Branch 2 taken 86 times.
✓ Branch 3 taken 500 times.
✓ Branch 4 taken 500 times.
✓ Branch 5 taken 11655 times.
12155 while((nmap!=0) && !looped && !(nscr>=128))
2867 {
2868
7/8
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 93 times.
✓ Branch 3 taken 295 times.
✓ Branch 4 taken 93 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 89 times.
500 if (nmap - 1 == cur_map && is_in_current_region(nscr) && !get_screen_state(nscr).triggered_secrets)
2869 {
2870
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
2871
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 trigger_secrets_for_screen_internal(create_screen_handles(get_scr(nscr)), from_active_screen, high16only, single, do_replay_comment);
2872
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 get_screen_state(nscr).triggered_secrets = true;
2873 4 }
2874
2875 500 cmap=nmap;
2876 500 cscr=nscr;
2877 500 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
2878 500 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
2879
2880
2/2
✓ Branch 0 taken 443 times.
✓ Branch 1 taken 500 times.
943 for(auto it = done.begin(); it != done.end(); it++)
2881 {
2882
2/2
✓ Branch 0 taken 357 times.
✓ Branch 1 taken 86 times.
443 if(*it == ((nmap-1)<<7)+nscr)
2883 86 looped = true;
2884 443 }
2885
2886
1/2
✓ Branch 0 taken 500 times.
✗ Branch 1 not taken.
500 done.push_back(((nmap-1)<<7)+nscr);
2887 }
2888 12132 }
2889
2890 2550 void trigger_secrets_for_screen(TriggerSource source, int32_t screen, bool high16only, int32_t single)
2891 {
2892 2550 trigger_secrets_for_screen(source, get_scr(screen), high16only, single);
2893 2550 }
2894
2895 19223 void trigger_secrets_for_screen_internal(const screen_handles_t& screen_handles, bool from_active_screen, bool high16only, int32_t single, bool do_replay_comment)
2896 {
2897 19223 mapscr* scr = screen_handles[0].scr;
2898 19223 int screen = scr->screen;
2899
2900 // TODO(replays): No real reason for "do_replay_comment" to exist - I just did not want to update many replays when fixing
2901 // slopes in sideview mode (which required loading nearby screens in loadscr).
2902 // TODO(replays): This should just use `screen`.
2903
3/4
✓ Branch 0 taken 19223 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 18684 times.
19223 if (replay_is_active() && do_replay_comment)
2904
4/6
✓ Branch 0 taken 12136 times.
✓ Branch 1 taken 6548 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12136 times.
✓ Branch 4 taken 18684 times.
✗ Branch 5 not taken.
18684 replay_step_comment(fmt::format("trigger secrets scr={}", from_active_screen && scr != special_warp_return_scr ? screen : cur_screen));
2905
2906
2/2
✓ Branch 0 taken 7087 times.
✓ Branch 1 taken 12136 times.
19223 if (from_active_screen)
2907 {
2908 6099822 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
2909
2/4
✓ Branch 0 taken 6085024 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2662 times.
✗ Branch 3 not taken.
6407603 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
2910 319917 return trig.trigger_flags.get(TRIGFLAG_SECRETSTR);
2911 }, ctrigSECRETS);
2912 6087686 });
2913 12136 }
2914
2915 19223 int32_t ft=0; //Flag trigger?
2916 19223 int32_t msflag=0; // Misc. secret flag
2917
2918
2/2
✓ Branch 0 taken 3383248 times.
✓ Branch 1 taken 19223 times.
3402471 for(int32_t i=0; i<176; i++) //Do the 'trigger flags' (non 16-31)
2919 {
2920
4/4
✓ Branch 0 taken 79552 times.
✓ Branch 1 taken 3303696 times.
✓ Branch 2 taken 452 times.
✓ Branch 3 taken 79100 times.
3383248 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2921
2922 // Remember the misc. secret flag; if triggered, use this instead
2923
4/4
✓ Branch 0 taken 153551 times.
✓ Branch 1 taken 3150597 times.
✓ Branch 2 taken 87558 times.
✓ Branch 3 taken 65993 times.
3304148 if(scr->sflag[i]>=mfSECRETS01 && scr->sflag[i]<=mfSECRETS16)
2924 65993 msflag=sSECRET01+(scr->sflag[i]-mfSECRETS01);
2925
4/4
✓ Branch 0 taken 47862 times.
✓ Branch 1 taken 3190293 times.
✓ Branch 2 taken 47336 times.
✓ Branch 3 taken 526 times.
3238155 else if(combobuf[scr->data[i]].flag>=mfSECRETS01 && combobuf[scr->data[i]].flag<=mfSECRETS16)
2926 526 msflag=sSECRET01+(combobuf[scr->data[i]].flag-mfSECRETS01);
2927 else
2928 3237629 msflag=0;
2929
2930
4/4
✓ Branch 0 taken 922853 times.
✓ Branch 1 taken 2381295 times.
✓ Branch 2 taken 85 times.
✓ Branch 3 taken 922768 times.
3304148 if(!high16only || single>=0)
2931 {
2932 2381380 int32_t newflag = -1;
2933
2934
2/2
✓ Branch 0 taken 4762760 times.
✓ Branch 1 taken 2381380 times.
7144140 for(int32_t iter=0; iter<2; ++iter)
2935 {
2936 4762760 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2937
2938
2/2
✓ Branch 0 taken 2381380 times.
✓ Branch 1 taken 2381380 times.
4762760 if(iter==1) checkflag=scr->sflag[i]; //Placed
2939
2940 4762760 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2941
2/2
✓ Branch 0 taken 4750287 times.
✓ Branch 1 taken 12473 times.
4762760 if (ft != -1) //Change the combos for the secret
2942 {
2943 // Use misc. secret flag instead if one is present
2944
2/2
✓ Branch 0 taken 12441 times.
✓ Branch 1 taken 32 times.
12473 if(msflag!=0)
2945 32 ft=msflag;
2946
2947 12473 rpos_handle_t rpos_handle;
2948
2/2
✓ Branch 0 taken 6541 times.
✓ Branch 1 taken 5932 times.
12473 if (from_active_screen)
2949 {
2950 5932 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2951 5932 screen_combo_modify_preroutine(rpos_handle);
2952 5932 }
2953
2954
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12473 times.
12473 if(ft==sSECNEXT)
2955 {
2956 scr->data[i]++;
2957 }
2958 else
2959 {
2960 12473 scr->data[i] = scr->secretcombo[ft];
2961 12473 scr->cset[i] = scr->secretcset[ft];
2962 }
2963 12473 newflag = scr->secretflag[ft];
2964
2965
2/2
✓ Branch 0 taken 6541 times.
✓ Branch 1 taken 5932 times.
12473 if (from_active_screen)
2966 5932 screen_combo_modify_postroutine(rpos_handle);
2967 12473 }
2968 4762760 }
2969
2970
2/2
✓ Branch 0 taken 2368913 times.
✓ Branch 1 taken 12467 times.
2381380 if(newflag >-1) scr->sflag[i] = newflag; //Tiered secret
2971
2972
2/2
✓ Branch 0 taken 14288280 times.
✓ Branch 1 taken 2381380 times.
16669660 for(int32_t j=1; j<=6; j++) //Layers
2973 {
2974 14288280 mapscr* layer_scr = screen_handles[j].scr;
2975
2/2
✓ Branch 0 taken 4300978 times.
✓ Branch 1 taken 9987302 times.
14288280 if (!layer_scr) continue;
2976
2977
3/4
✓ Branch 0 taken 770 times.
✓ Branch 1 taken 4300208 times.
✓ Branch 2 taken 770 times.
✗ Branch 3 not taken.
4300978 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2978
2979 4300978 int32_t newflag2 = -1;
2980
2981 // Remember the misc. secret flag; if triggered, use this instead
2982
4/4
✓ Branch 0 taken 18068 times.
✓ Branch 1 taken 4282910 times.
✓ Branch 2 taken 6284 times.
✓ Branch 3 taken 11784 times.
4300978 if(layer_scr->sflag[i]>=mfSECRETS01 && layer_scr->sflag[i]<=mfSECRETS16)
2983 11784 msflag=sSECRET01+(layer_scr->sflag[i]-mfSECRETS01);
2984
4/4
✓ Branch 0 taken 132026 times.
✓ Branch 1 taken 4157168 times.
✓ Branch 2 taken 130774 times.
✓ Branch 3 taken 1252 times.
4289194 else if(combobuf[layer_scr->data[i]].flag>=mfSECRETS01 && combobuf[layer_scr->data[i]].flag<=mfSECRETS16)
2985 1252 msflag=sSECRET01+(combobuf[layer_scr->data[i]].flag-mfSECRETS01);
2986 else
2987 4287942 msflag=0;
2988
2989
2/2
✓ Branch 0 taken 8601956 times.
✓ Branch 1 taken 4300978 times.
12902934 for(int32_t iter=0; iter<2; ++iter)
2990 {
2991 8601956 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2992
2/2
✓ Branch 0 taken 4300978 times.
✓ Branch 1 taken 4300978 times.
8601956 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2993
2994 8601956 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2995
2/2
✓ Branch 0 taken 8600177 times.
✓ Branch 1 taken 1779 times.
8601956 if (ft != -1) //Change the combos for the secret
2996 {
2997 // Use misc. secret flag instead if one is present
2998
2/2
✓ Branch 0 taken 1777 times.
✓ Branch 1 taken 2 times.
1779 if(msflag!=0)
2999 2 ft=msflag;
3000
3001
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1779 times.
1779 if(ft==sSECNEXT)
3002 {
3003 layer_scr->data[i]++;
3004 }
3005 else
3006 {
3007 1779 layer_scr->data[i] = layer_scr->secretcombo[ft];
3008 1779 layer_scr->cset[i] = layer_scr->secretcset[ft];
3009 }
3010 1779 newflag2 = layer_scr->secretflag[ft];
3011 1779 int32_t c=layer_scr->data[i];
3012 1779 int32_t cs=layer_scr->cset[i];
3013
3014
3/4
✓ Branch 0 taken 908 times.
✓ Branch 1 taken 871 times.
✓ Branch 2 taken 908 times.
✗ Branch 3 not taken.
1779 if (from_active_screen && combobuf[c].type==cSPINTILE1) //Surely this means we can have spin tiles on layers 3+? Isn't that bad? ~Joe123
3015 {
3016 auto [offx, offy] = translate_screen_coordinates_to_world(screen, COMBOX(i), COMBOY(i));
3017 addenemy(screen,offx,offy,(cs<<12)+eSPINTILE1,combobuf[c].o_tile+zc_max(1,combobuf[c].frames));
3018 }
3019 1779 }
3020 8601956 }
3021
3022
2/2
✓ Branch 0 taken 1766 times.
✓ Branch 1 taken 4299212 times.
4300978 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered secret
3023 4300978 }
3024 2381380 }
3025 3304148 }
3026
3027 19223 word c = scr->numFFC();
3028
2/2
✓ Branch 0 taken 508334 times.
✓ Branch 1 taken 19223 times.
527557 for(word i=0; i<c; i++) //FFC 'trigger flags'
3029 {
3030
3/4
✓ Branch 0 taken 494280 times.
✓ Branch 1 taken 14054 times.
✓ Branch 2 taken 14054 times.
✗ Branch 3 not taken.
508334 if(single>=0) if(i+176!=single) continue;
3031
3032
3/4
✓ Branch 0 taken 166649 times.
✓ Branch 1 taken 327631 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 166649 times.
494280 if((!high16only)||(single>=0))
3033 {
3034 //for (int32_t iter=0; iter<1; ++iter) // Only one kind of FFC flag now.
3035 {
3036 327631 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3037 //No placed flags yet
3038
3039 327631 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
3040
2/2
✓ Branch 0 taken 327600 times.
✓ Branch 1 taken 31 times.
327631 if (ft != -1) //Change the ffc's combo
3041 {
3042
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(ft==sSECNEXT)
3043 {
3044 zc_ffc_modify(scr->ffcs[i], 1);
3045 }
3046 else
3047 {
3048 31 zc_ffc_set(scr->ffcs[i], scr->secretcombo[ft]);
3049 31 scr->ffcs[i].cset = scr->secretcset[ft];
3050 }
3051 31 }
3052 }
3053 327631 }
3054 494280 }
3055
3056
2/2
✓ Branch 0 taken 16725 times.
✓ Branch 1 taken 2498 times.
19223 if(checktrigger) //Hit all triggers->16-31
3057 {
3058 2498 checktrigger=false;
3059
3060
2/2
✓ Branch 0 taken 2474 times.
✓ Branch 1 taken 24 times.
2498 if(scr->flags6&fTRIGGERF1631)
3061 {
3062 24 int32_t tr = findtrigger(screen); //Normal flags
3063
3064
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 10 times.
24 if(tr)
3065 {
3066 14 Z_eventlog("Hit All Triggers->16-31 not fulfilled (%d trigger flag%s remain).\n", tr, tr>1?"s":"");
3067 14 goto endhe;
3068 }
3069 10 }
3070 2484 }
3071
3072
2/2
✓ Branch 0 taken 3380784 times.
✓ Branch 1 taken 19209 times.
3399993 for(int32_t i=0; i<176; i++) // Do the 16-31 secrets
3073 {
3074 //If it's an enemies->secret screen, only do the high 16 if told to
3075 //That way you can have secret and burn/bomb entrance separately
3076 3380784 bool old_enem_secret = get_qr(qr_ENEMIES_SECRET_ONLY_16_31);
3077
6/6
✓ Branch 0 taken 2780624 times.
✓ Branch 1 taken 600160 times.
✓ Branch 2 taken 85184 times.
✓ Branch 3 taken 3295600 times.
✓ Branch 4 taken 19536 times.
✓ Branch 5 taken 65648 times.
3380784 if(((!(old_enem_secret && (scr->flags2&fCLEARSECRET)) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM))
3078 {
3079 3315136 int32_t newflag = -1;
3080
3081
2/2
✓ Branch 0 taken 6630272 times.
✓ Branch 1 taken 3315136 times.
9945408 for(int32_t iter=0; iter<2; ++iter)
3082 {
3083 6630272 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
3084
3085
2/2
✓ Branch 0 taken 3315136 times.
✓ Branch 1 taken 3315136 times.
6630272 if(iter==1) checkflag=scr->sflag[i]; //Placed
3086
3087
4/4
✓ Branch 0 taken 200805 times.
✓ Branch 1 taken 6429467 times.
✓ Branch 2 taken 133230 times.
✓ Branch 3 taken 67575 times.
6630272 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3088 {
3089 67575 rpos_handle_t rpos_handle;
3090
2/2
✓ Branch 0 taken 10367 times.
✓ Branch 1 taken 57208 times.
67575 if (from_active_screen)
3091 {
3092 57208 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
3093 57208 screen_combo_modify_preroutine(rpos_handle);
3094 57208 }
3095
3096 67575 scr->data[i] = scr->secretcombo[checkflag-16+4];
3097 67575 scr->cset[i] = scr->secretcset[checkflag-16+4];
3098 67575 newflag = scr->secretflag[checkflag-16+4];
3099
3100
2/2
✓ Branch 0 taken 10367 times.
✓ Branch 1 taken 57208 times.
67575 if (from_active_screen)
3101 57208 screen_combo_modify_postroutine(rpos_handle);
3102 67575 }
3103 6630272 }
3104
3105
2/2
✓ Branch 0 taken 3247589 times.
✓ Branch 1 taken 67547 times.
3315136 if(newflag >-1) scr->sflag[i] = newflag; //Tiered flag
3106
3107
2/2
✓ Branch 0 taken 19890816 times.
✓ Branch 1 taken 3315136 times.
23205952 for(int32_t j=1; j<=6; j++) //Layers
3108 {
3109 19890816 mapscr* layer_scr = screen_handles[j].scr;
3110
2/2
✓ Branch 0 taken 5992096 times.
✓ Branch 1 taken 13898720 times.
19890816 if (!layer_scr) continue;
3111
3112 5992096 int32_t newflag2 = -1;
3113
3114
2/2
✓ Branch 0 taken 11984192 times.
✓ Branch 1 taken 5992096 times.
17976288 for(int32_t iter=0; iter<2; ++iter)
3115 {
3116 11984192 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
3117
3118
2/2
✓ Branch 0 taken 5992096 times.
✓ Branch 1 taken 5992096 times.
11984192 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
3119
3120
4/4
✓ Branch 0 taken 159433 times.
✓ Branch 1 taken 11824759 times.
✓ Branch 2 taken 136546 times.
✓ Branch 3 taken 22887 times.
11984192 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3121 {
3122 22887 layer_scr->data[i] = layer_scr->secretcombo[checkflag-16+4];
3123 22887 layer_scr->cset[i] = layer_scr->secretcset[checkflag-16+4];
3124 22887 newflag2 = layer_scr->secretflag[checkflag-16+4];
3125 22887 }
3126 11984192 }
3127
3128
2/2
✓ Branch 0 taken 5969209 times.
✓ Branch 1 taken 22887 times.
5992096 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered flag
3129 5992096 }
3130 3315136 }
3131 3380784 }
3132
3133
2/2
✓ Branch 0 taken 508074 times.
✓ Branch 1 taken 19209 times.
527283 for(word i=0; i<c; i++) // FFCs
3134 {
3135
6/6
✓ Branch 0 taken 468053 times.
✓ Branch 1 taken 40021 times.
✓ Branch 2 taken 15497 times.
✓ Branch 3 taken 492577 times.
✓ Branch 4 taken 3657 times.
✓ Branch 5 taken 11840 times.
508074 if((!(scr->flags2&fCLEARSECRET) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM)
3136 {
3137 496234 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3138
3139 //No placed flags yet
3140
4/4
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 496141 times.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 12 times.
496234 if((checkflag > 15)&&(checkflag < 32)) //If we find a flag, change the combo
3141 {
3142
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (from_active_screen)
3143 9 zc_ffc_set(scr->ffcs[i], scr->secretcombo[checkflag - 16 + 4]);
3144 else
3145 3 scr->ffcs[i].data = scr->secretcombo[checkflag - 16 + 4];
3146 12 scr->ffcs[i].cset = scr->secretcset[checkflag-16+4];
3147 12 }
3148 496234 }
3149 527283 }
3150
3151 endhe:
3152
3153
1/2
✓ Branch 0 taken 19223 times.
✗ Branch 1 not taken.
19223 if (scr->flags4&fDISABLETIME) //Finish timed warp if 'Secrets Disable Timed Warp'
3154 {
3155 if (from_active_screen)
3156 activated_timed_warp = true;
3157 scr->timedwarptics = 0;
3158 }
3159 19223 }
3160
3161 // x,y are world coordinates.
3162 // Returns true if there is a flag (either combo, screen, or ffc) at (x, y).
3163 // Out parameters will be set if the flag is Trigger->Self, which modifies how secrets will be triggered.
3164 13982906 static bool has_flag_trigger(int32_t x, int32_t y, int32_t flag, rpos_t& out_rpos, bool& out_single16)
3165 {
3166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13982906 times.
13982906 if (!is_in_world_bounds(x, y)) return false;
3167
3168 13982906 bool found_cflag = false;
3169 13982906 bool found_nflag = false;
3170 13982906 bool single16 = false;
3171 13982906 rpos_t rpos = rpos_t::None;
3172
3173
2/2
✓ Branch 0 taken 13980804 times.
✓ Branch 1 taken 97868060 times.
111848864 for (int32_t layer = -1; layer < 6; layer++)
3174 {
3175
2/2
✓ Branch 0 taken 97865958 times.
✓ Branch 1 taken 2102 times.
97868060 if (MAPFLAG2(layer, x, y) == flag)
3176 {
3177 2102 found_nflag = true;
3178 2102 break;
3179 }
3180 97865958 }
3181
3182
2/2
✓ Branch 0 taken 13982517 times.
✓ Branch 1 taken 97878647 times.
111861164 for (int32_t layer = -1; layer < 6; layer++)
3183 {
3184
2/2
✓ Branch 0 taken 97878258 times.
✓ Branch 1 taken 389 times.
97878647 if (MAPCOMBOFLAG2(layer, x, y) == flag)
3185 {
3186 389 found_cflag = true;
3187 389 break;
3188 }
3189 97878258 }
3190
3191
2/2
✓ Branch 0 taken 97880342 times.
✓ Branch 1 taken 13982906 times.
111863248 for (int32_t i=-1; i<6; i++) // Look for Trigger->Self on all layers
3192 {
3193
2/2
✓ Branch 0 taken 97865628 times.
✓ Branch 1 taken 14714 times.
97880342 if (found_nflag) // Trigger->Self (a.k.a Singular) is inherent
3194 {
3195
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14602 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
14714 if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE) && (MAPFLAG2(i, x, y) == flag))
3196 {
3197 112 rpos = COMBOPOS_REGION(x, y);
3198 112 }
3199
3/4
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 14546 times.
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
14602 else if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE16) && (MAPFLAG2(i, x, y) == flag))
3200 {
3201 56 rpos = COMBOPOS_REGION(x, y);
3202 56 single16 = true;
3203 56 }
3204 14714 }
3205
3206
2/2
✓ Branch 0 taken 97877619 times.
✓ Branch 1 taken 2723 times.
97880342 if (found_cflag) // Trigger->Self (a.k.a Singular) is non-inherent
3207 {
3208
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 2468 times.
✓ Branch 2 taken 255 times.
✗ Branch 3 not taken.
2723 if ((MAPFLAG2(i, x, y) == mfSINGLE) && (MAPCOMBOFLAG2(i, x, y) == flag))
3209 {
3210 255 rpos = COMBOPOS_REGION(x, y);
3211 255 }
3212
3/4
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 2439 times.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
2468 else if ((MAPFLAG2(i, x, y) == mfSINGLE16) && (MAPCOMBOFLAG2(i, x, y) == flag))
3213 {
3214 29 rpos = COMBOPOS_REGION(x, y);
3215 29 single16 = true;
3216 29 }
3217 2723 }
3218 97880342 }
3219
3220 13982906 out_rpos = rpos;
3221 13982906 out_single16 = single16;
3222
4/4
✓ Branch 0 taken 13980804 times.
✓ Branch 1 taken 2102 times.
✓ Branch 2 taken 13980419 times.
✓ Branch 3 taken 385 times.
13982906 return found_nflag || found_cflag || MAPFFCOMBOFLAG(x,y) == flag;
3223 13982906 }
3224
3225 4604586 bool trigger_secrets_if_flag(int32_t x, int32_t y, int32_t flag, bool setflag)
3226 {
3227
8/8
✓ Branch 0 taken 4604346 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 4602449 times.
✓ Branch 3 taken 1897 times.
✓ Branch 4 taken 4601929 times.
✓ Branch 5 taken 520 times.
✓ Branch 6 taken 952 times.
✓ Branch 7 taken 4600977 times.
4604586 if (x < -16 || y < -16 || x >= world_w || y >= world_h) return false;
3228
3229 4600977 mapscr* scr = NULL;
3230 4600977 int32_t screen = -1;
3231 4600977 rpos_t trigger_rpos = rpos_t::None;
3232 4600977 bool single16 = false;
3233
3234 4600977 std::vector<std::pair<int, int>> coords;
3235
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x, y});
3236
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x + 15, y});
3237
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x, y + 15});
3238
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x + 15, y + 15});
3239 4600977 std::vector<rpos_t> rposes_seen;
3240
2/2
✓ Branch 0 taken 4598479 times.
✓ Branch 1 taken 18398387 times.
87336590 for (auto [x, y] : coords)
3241 {
3242
2/4
✓ Branch 0 taken 18398387 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18398387 times.
✗ Branch 3 not taken.
36796774 rpos_t rpos = COMBOPOS_REGION_B(x, y);
3243
2/2
✓ Branch 0 taken 18184458 times.
✓ Branch 1 taken 213929 times.
18398387 if (rpos == rpos_t::None)
3244 213929 continue;
3245
3246
4/6
✓ Branch 0 taken 18184458 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18184458 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 18184447 times.
36368916 if (MAPFFCOMBOFLAG(x, y) == flag)
3247 {
3248
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 screen = get_screen_for_world_xy(x, y);
3249 11 break;
3250 }
3251
3252 18184447 bool seen = false;
3253
2/2
✓ Branch 0 taken 13982906 times.
✓ Branch 1 taken 22894140 times.
36877046 for (rpos_t r : rposes_seen)
3254 {
3255
2/2
✓ Branch 0 taken 18692599 times.
✓ Branch 1 taken 4201541 times.
22894140 if (r == rpos)
3256 {
3257 4201541 seen = true;
3258 4201541 break;
3259 }
3260 }
3261
2/2
✓ Branch 0 taken 13982906 times.
✓ Branch 1 taken 4201541 times.
18184447 if (seen)
3262 4201541 continue;
3263
3264
1/2
✓ Branch 0 taken 13982906 times.
✗ Branch 1 not taken.
13982906 rposes_seen.push_back(rpos);
3265
4/6
✓ Branch 0 taken 13982906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13982906 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2487 times.
✓ Branch 5 taken 13980419 times.
27965812 if (has_flag_trigger(x, y, flag, trigger_rpos, single16))
3266 {
3267
2/4
✓ Branch 0 taken 2487 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2487 times.
✗ Branch 3 not taken.
4974 screen = get_screen_for_world_xy(x, y);
3268 2487 break;
3269 }
3270 }
3271
3272
3/4
✓ Branch 0 taken 2498 times.
✓ Branch 1 taken 4598479 times.
✓ Branch 2 taken 2498 times.
✗ Branch 3 not taken.
4600977 if (screen != -1) scr = get_scr(screen);
3273
2/2
✓ Branch 0 taken 2498 times.
✓ Branch 1 taken 4598479 times.
4600977 if (!scr) return false;
3274
3275
2/2
✓ Branch 0 taken 2046 times.
✓ Branch 1 taken 452 times.
2498 if (trigger_rpos == rpos_t::None)
3276 {
3277 2046 checktrigger = true;
3278
1/2
✓ Branch 0 taken 2046 times.
✗ Branch 1 not taken.
2046 trigger_secrets_for_screen(TriggerSource::Unspecified, screen);
3279 2046 }
3280 else
3281 {
3282 452 checktrigger = true;
3283
2/4
✓ Branch 0 taken 452 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 452 times.
✗ Branch 3 not taken.
452 trigger_secrets_for_screen(TriggerSource::Singular, scr, single16, RPOS_TO_POS(trigger_rpos));
3284 }
3285
3286
1/2
✓ Branch 0 taken 2498 times.
✗ Branch 1 not taken.
2498 sfx(scr->secretsfx);
3287
3288
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 2477 times.
2498 if(scr->flags6&fTRIGGERFPERM)
3289 {
3290
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 int32_t flags_remaining = findtrigger(screen); //Normal flags
3291
3292
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 9 times.
21 if (flags_remaining)
3293 {
3294
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 Z_eventlog("Hit All Triggers->Perm Secret not fulfilled (%d trigger flag%s remain).\n", flags_remaining, flags_remaining>1?"s":"");
3295 12 setflag=false;
3296 12 }
3297
3298 // Only actually trigger secrets now if 1) all triggers are gone and 2) QR qr_ALLTRIG_PERMSEC_NO_TEMP is off, in
3299 // which case only the screen state for mSECRET may be set below.
3300
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 3 times.
21 if (!flags_remaining && !get_qr(qr_ALLTRIG_PERMSEC_NO_TEMP))
3301 {
3302
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 trigger_secrets_for_screen(TriggerSource::Unspecified, scr, scr->flags6&fTRIGGERF1631, -1);
3303 6 }
3304 21 }
3305
3306
5/6
✓ Branch 0 taken 2384 times.
✓ Branch 1 taken 114 times.
✓ Branch 2 taken 2384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1108 times.
✓ Branch 5 taken 1276 times.
2498 if (setflag && canPermSecret(cur_dmap, screen))
3307
2/2
✓ Branch 0 taken 813 times.
✓ Branch 1 taken 463 times.
2089 if(!(scr->flags5&fTEMPSECRETS))
3308
1/2
✓ Branch 0 taken 813 times.
✗ Branch 1 not taken.
813 setmapflag(scr, mSECRET);
3309
3310 2498 return true;
3311 4604586 }
3312
3313 15383791 void update_slopes()
3314 {
3315
2/2
✓ Branch 0 taken 142356 times.
✓ Branch 1 taken 15383791 times.
15526147 for (auto& p : slopes)
3316 {
3317 142356 slope_object& s = p.second;
3318 142356 s.updateslope(); //sets old x/y poses
3319 }
3320 15383791 }
3321
3322 14926345 void update_freeform_combos()
3323 {
3324 14926345 ffscript_engine(false);
3325
2/2
✓ Branch 0 taken 24172 times.
✓ Branch 1 taken 14902173 times.
14926345 if ( !FFCore.system_suspend[susptUPDATEFFC] )
3326 {
3327 14902173 int wrap_right = world_w + 32;
3328 14902173 int wrap_bottom = world_h + 32;
3329
3330 488483733 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
3331 473581560 mapscr* scr = ffc_handle.scr;
3332 473581560 ffcdata& thisffc = *ffc_handle.ffc;
3333
3334 // Combo 0?
3335
2/2
✓ Branch 0 taken 47283383 times.
✓ Branch 1 taken 426298177 times.
473581560 if(thisffc.data==0)
3336 426298177 return;
3337
3338 // Changer?
3339
2/2
✓ Branch 0 taken 562821 times.
✓ Branch 1 taken 46720562 times.
47283383 if(thisffc.flags&ffc_changer)
3340 562821 return;
3341
3342 // Stationary?
3343
2/2
✓ Branch 0 taken 9844 times.
✓ Branch 1 taken 46710718 times.
46720562 if(thisffc.flags&ffc_stationary)
3344 9844 return;
3345
3346 // Frozen because Hero's holding up an item?
3347
3/4
✓ Branch 0 taken 157429 times.
✓ Branch 1 taken 46553289 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 157429 times.
46710718 if(Hero.getHoldClk()>0 && (thisffc.flags&ffc_ignoreholdup)==0)
3348 157429 return;
3349
3350 // Check for changers
3351
2/2
✓ Branch 0 taken 31045254 times.
✓ Branch 1 taken 15508035 times.
46553289 if (thisffc.link==0)
3352 {
3353 446641803 for_some_ffcs([&](const ffc_handle_t& other_ffc_handle) {
3354
2/2
✓ Branch 0 taken 15506398 times.
✓ Branch 1 taken 415627370 times.
431133768 if (ffc_handle.id == other_ffc_handle.id)
3355 15506398 return true;
3356
3357 415627370 ffcdata& otherffc = *other_ffc_handle.ffc;
3358 // Combo 0?
3359
2/2
✓ Branch 0 taken 147056016 times.
✓ Branch 1 taken 268571354 times.
415627370 if(otherffc.data==0)
3360 268571354 return true;
3361
3362 // Not a changer?
3363
2/2
✓ Branch 0 taken 142873987 times.
✓ Branch 1 taken 4182029 times.
147056016 if(!(otherffc.flags&ffc_changer))
3364 142873987 return true;
3365
3366 // Ignore this changer?
3367
4/4
✓ Branch 0 taken 564215 times.
✓ Branch 1 taken 3617814 times.
✓ Branch 2 taken 308097 times.
✓ Branch 3 taken 3309717 times.
4182029 if((otherffc.x.getInt()==thisffc.changer_x&&otherffc.y.getInt()==thisffc.changer_y) || thisffc.flags&ffc_ignorechanger)
3368 872312 return true;
3369
3370
3/4
✓ Branch 0 taken 2870799 times.
✓ Branch 1 taken 438918 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3663 times.
3313380 if((isonline(thisffc.x.getZLong(), thisffc.y.getZLong(), thisffc.prev_changer_x, thisffc.prev_changer_y, otherffc.x.getZLong(), otherffc.y.getZLong()) || // Along the line, or...
3371 ( // At exactly the same position,
3372
2/2
✓ Branch 0 taken 217547 times.
✓ Branch 1 taken 2653252 times.
2870799 (thisffc.x==otherffc.x && thisffc.y==otherffc.y))
3373
2/2
✓ Branch 0 taken 2435705 times.
✓ Branch 1 taken 2653252 times.
217547 ||
3374 //or imprecision and close enough
3375
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5306504 ( (thisffc.flags&ffc_imprecisionchanger) && ((abs(thisffc.x.getZLong() - otherffc.x.getZLong()) < 10000) && abs(thisffc.y.getZLong() - otherffc.y.getZLong()) < 10000) )
3376 )
3377 && //and...
3378
2/2
✓ Branch 0 taken 3663 times.
✓ Branch 1 taken 2870960 times.
2874623 (thisffc.prev_changer_x>-10000000 && thisffc.prev_changer_y>-10000000)) // This isn't the first frame on this screen
3379 {
3380 3663 zc_ffc_changer(thisffc, otherffc, ffc_handle.id, other_ffc_handle.id);
3381 3663 return false;
3382 }
3383
3384 2870960 return true;
3385 430082480 });
3386 15508035 }
3387
3388
2/2
✓ Branch 0 taken 31045254 times.
✓ Branch 1 taken 15508035 times.
46553289 ffcdata* linked_ffc = thisffc.link ? get_ffc_handle(thisffc.link - 1).ffc : nullptr;
3389
4/4
✓ Branch 0 taken 15508035 times.
✓ Branch 1 taken 31045254 times.
✓ Branch 2 taken 15430742 times.
✓ Branch 3 taken 15614512 times.
46553289 if (linked_ffc ? !linked_ffc->delay : !thisffc.delay)
3390 {
3391
4/4
✓ Branch 0 taken 182609 times.
✓ Branch 1 taken 15431903 times.
✓ Branch 2 taken 85331 times.
✓ Branch 3 taken 97278 times.
15614512 if(thisffc.link && (thisffc.link-1) != ffc_handle.id)
3392 {
3393 97278 thisffc.prev_changer_x = thisffc.x.getZLong();
3394 97278 thisffc.prev_changer_y = thisffc.y.getZLong();
3395 97278 thisffc.x += linked_ffc->vx;
3396 97278 thisffc.y += linked_ffc->vy;
3397 97278 }
3398 else
3399 {
3400 15517234 thisffc.prev_changer_x = thisffc.x.getZLong();
3401 15517234 thisffc.prev_changer_y = thisffc.y.getZLong();
3402 15517234 thisffc.x += thisffc.vx;
3403 15517234 thisffc.y += thisffc.vy;
3404 15517234 thisffc.vx += thisffc.ax;
3405 15517234 thisffc.vy += thisffc.ay;
3406
3407
3408
2/2
✓ Branch 0 taken 1192049 times.
✓ Branch 1 taken 14325185 times.
15517234 if(get_qr(qr_OLD_FFC_SPEED_CAP))
3409 {
3410
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vx>128) thisffc.vx=128;
3411
3412
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vx<-128) thisffc.vx=-128;
3413
3414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vy>128) thisffc.vy=128;
3415
3416
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vy<-128) thisffc.vy=-128;
3417 14325185 }
3418 }
3419 15614512 }
3420 else
3421 {
3422
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 76132 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1161 times.
30938777 if(!thisffc.link || (thisffc.link-1) == ffc_handle.id)
3423 76132 thisffc.delay--;
3424 }
3425
3426 // Check if the FFC's off the side of the screen
3427
3428 // Left
3429
2/2
✓ Branch 0 taken 10449 times.
✓ Branch 1 taken 15681356 times.
15691805 if(thisffc.x<-32)
3430 {
3431
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 10196 times.
10449 if(scr->flags6&fWRAPAROUNDFF)
3432 {
3433 253 thisffc.x = wrap_right+(thisffc.x+32);
3434 253 thisffc.solid_update(false);
3435 253 thisffc.prev_changer_y = thisffc.y.getZLong();
3436 // Re-enable previous changer
3437 253 thisffc.changer_x = -1000;
3438 253 thisffc.changer_y = -1000;
3439 253 }
3440
2/2
✓ Branch 0 taken 10127 times.
✓ Branch 1 taken 69 times.
10196 else if(thisffc.x<-64)
3441 {
3442 69 zc_ffc_set(thisffc, 0);
3443 69 thisffc.flags&=~ffc_carryover;
3444 69 }
3445 10449 }
3446 // Right
3447
2/2
✓ Branch 0 taken 15681175 times.
✓ Branch 1 taken 181 times.
15681356 else if(thisffc.x>=wrap_right)
3448 {
3449
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 53 times.
181 if(scr->flags6&fWRAPAROUNDFF)
3450 {
3451 128 thisffc.x = thisffc.x-wrap_right-32;
3452 128 thisffc.solid_update(false);
3453 128 thisffc.prev_changer_y = thisffc.y.getZLong();
3454 128 thisffc.changer_x = -1000;
3455 128 thisffc.changer_y = -1000;
3456 128 }
3457 else
3458 {
3459 53 zc_ffc_set(thisffc, 0);
3460 53 thisffc.flags&=~ffc_carryover;
3461 }
3462 181 }
3463
3464 // Top
3465
2/2
✓ Branch 0 taken 25806 times.
✓ Branch 1 taken 15665999 times.
15691805 if(thisffc.y<-32)
3466 {
3467
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25798 times.
25806 if(scr->flags6&fWRAPAROUNDFF)
3468 {
3469 8 thisffc.y = wrap_bottom+(thisffc.y+32);
3470 8 thisffc.solid_update(false);
3471 8 thisffc.prev_changer_x = thisffc.x.getZLong();
3472 8 thisffc.changer_x = -1000;
3473 8 thisffc.changer_y = -1000;
3474 8 }
3475
2/2
✓ Branch 0 taken 25481 times.
✓ Branch 1 taken 317 times.
25798 else if(thisffc.y<-64)
3476 {
3477 317 zc_ffc_set(thisffc, 0);
3478 317 thisffc.flags&=~ffc_carryover;
3479 317 }
3480 25806 }
3481 // Bottom
3482
2/2
✓ Branch 0 taken 15665131 times.
✓ Branch 1 taken 868 times.
15665999 else if(thisffc.y>=wrap_bottom)
3483 {
3484
2/2
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 115 times.
868 if(scr->flags6&fWRAPAROUNDFF)
3485 {
3486 753 thisffc.y = thisffc.y-wrap_bottom-32;
3487 753 thisffc.solid_update(false);
3488 753 thisffc.prev_changer_y = thisffc.x.getZLong();
3489 753 thisffc.changer_x = -1000;
3490 753 thisffc.changer_y = -1000;
3491 753 }
3492 else
3493 {
3494 115 zc_ffc_set(thisffc, 0);
3495 115 thisffc.flags&=~ffc_carryover;
3496 }
3497 868 }
3498 15691805 thisffc.solid_update();
3499 442720076 });
3500 14902173 }
3501 14926345 }
3502
3503 bool hitflag(int32_t x, int32_t y, int32_t flagtype, byte layers)
3504 {
3505 for(int q = 0; q < 7; ++q)
3506 {
3507 if(layers&(1<<q)) //if layer is to be checked
3508 if(MAPFLAG2(q-1,x,y)==flagtype||MAPCOMBOFLAG2(q-1,x,y)==flagtype) //matching flag
3509 return true;
3510 }
3511 return false;
3512 }
3513
3514 231 optional<int> nextscr(int screen, int dir)
3515 {
3516 231 auto [m, s] = nextscr2(cur_map, screen, dir);
3517
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231 times.
231 if (m == -1) return nullopt;
3518 462 return (m<<7) + s;
3519 231 }
3520
3521 1064 std::pair<int32_t, int32_t> nextscr2(int32_t dir)
3522 {
3523 1064 int32_t map = cur_map;
3524
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1064 times.
1064 int32_t screen = screenscrolling ? scrolling_hero_screen : Hero.current_screen;
3525 1064 return nextscr2(map, screen, dir);
3526 }
3527
3528 5582 std::pair<int32_t, int32_t> nextscr2(int map, int screen, int32_t dir)
3529 {
3530 5582 screen = screen_index_direction(screen, (direction)dir);
3531
3532 // need to check for screens on other maps, 's' not valid, etc.
3533 5582 int32_t index = (hero_scr->sidewarpindex >> (dir*2))&3;
3534
3535 // Fun fact: when a scrolling warp is triggered, this function
3536 // is never even called! - Saf
3537
2/2
✓ Branch 0 taken 3330 times.
✓ Branch 1 taken 2252 times.
6126 if(hero_scr->sidewarptype[index] == 3) // scrolling warp
3538 {
3539
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 527 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 697 times.
2252 switch(dir)
3540 {
3541 case up:
3542
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 399 times.
482 if(!(hero_scr->flags2&wfUP)) goto nowarp;
3543
3544 83 break;
3545
3546 case down:
3547
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 448 times.
527 if(!(hero_scr->flags2&wfDOWN)) goto nowarp;
3548
3549 79 break;
3550
3551 case left:
3552
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 337 times.
546 if(!(hero_scr->flags2&wfLEFT)) goto nowarp;
3553
3554 209 break;
3555
3556 case right:
3557
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 524 times.
697 if(!(hero_scr->flags2&wfRIGHT)) goto nowarp;
3558
3559 173 break;
3560 }
3561
3562 544 map = DMaps[hero_scr->sidewarpdmap[index]].map;
3563 544 screen = hero_scr->sidewarpscr[index] + DMaps[hero_scr->sidewarpdmap[index]].xoff;
3564 544 }
3565
3566 nowarp:
3567
4/4
✓ Branch 0 taken 5518 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 5406 times.
5582 if(screen<0||screen>=128)
3568 176 return {-1, -1};
3569
3570 5406 return {map, screen};
3571 5582 }
3572
3573 403 optional<int> nextscr_mi(int mi, int dir)
3574 {
3575 403 int map = mi/MAPSCRSNORMAL;
3576 403 int screen = mi%MAPSCRSNORMAL;
3577 403 auto [m, s] = nextscr2(map, screen, dir);
3578
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 402 times.
403 if (m == -1) return nullopt;
3579 804 return (m<<7) + s;
3580 403 }
3581
3582 2297 void bombdoor(int32_t x,int32_t y)
3583 {
3584
2/2
✓ Branch 0 taken 2276 times.
✓ Branch 1 taken 21 times.
2297 if (!is_in_world_bounds(x, y))
3585 21 return;
3586
3587 2276 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
3588 2276 mapscr* scr = rpos_handle.scr;
3589 2276 int screen = scr->screen;
3590 3084 auto [x0, y0] = translate_screen_coordinates_to_world(rpos_handle.screen);
3591 #define CHECK_RECT(x,y,rx1,ry1,rx2,ry2) (isinRect(x,y,x0+rx1,y0+ry1,x0+rx2,y0+ry2))
3592
3593
12/12
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 2197 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 69 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 69 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 69 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 69 times.
2276 if(scr->door[0]==dBOMB && CHECK_RECT(x,y,100,0,139,48))
3594 {
3595 69 scr->door[0]=dBOMBED;
3596 69 putdoor(scr, scrollbuf, 0, dBOMBED);
3597 69 setmapflag(scr, mDOOR_UP);
3598 69 markBmap(-1, screen);
3599
3600
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 if(auto v = nextscr(screen, up))
3601 {
3602 69 setmapflag_mi(*v, mDOOR_DOWN);
3603 69 markBmap(-1,*v-(get_currdmap()<<7));
3604 69 }
3605 69 }
3606
3607
12/12
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2227 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 39 times.
2276 if(scr->door[1]==dBOMB && CHECK_RECT(x,y,100,112,139,176))
3608 {
3609 39 scr->door[1]=dBOMBED;
3610 39 putdoor(scr, scrollbuf, 1, dBOMBED);
3611 39 setmapflag(scr, mDOOR_DOWN);
3612 39 markBmap(-1, rpos_handle.screen);
3613
3614
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if(auto v = nextscr(rpos_handle.screen, down))
3615 {
3616 39 setmapflag_mi(*v, mDOOR_UP);
3617 39 markBmap(-1,*v-(get_currdmap()<<7));
3618 39 }
3619 39 }
3620
3621
12/12
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 2209 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 51 times.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 51 times.
2276 if(scr->door[2]==dBOMB && CHECK_RECT(x,y,0,60,48,98))
3622 {
3623 51 scr->door[2]=dBOMBED;
3624 51 putdoor(scr, scrollbuf, 2, dBOMBED);
3625 51 setmapflag(scr, mDOOR_LEFT);
3626 51 markBmap(-1, rpos_handle.screen);
3627
3628
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto v = nextscr(rpos_handle.screen, left))
3629 {
3630 51 setmapflag_mi(*v, mDOOR_RIGHT);
3631 51 markBmap(-1,*v-(get_currdmap()<<7));
3632 51 }
3633 51 }
3634
3635
12/12
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2190 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 72 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 72 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 72 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 72 times.
2276 if(scr->door[3]==dBOMB && CHECK_RECT(x,y,192,60,240,98))
3636 {
3637 72 scr->door[3]=dBOMBED;
3638 72 putdoor(scr, scrollbuf, 3, dBOMBED);
3639 72 setmapflag(scr, mDOOR_RIGHT);
3640 72 markBmap(-1, rpos_handle.screen);
3641
3642
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if(auto v = nextscr(rpos_handle.screen, right))
3643 {
3644 72 setmapflag_mi(*v, mDOOR_LEFT);
3645 72 markBmap(-1,*v-(get_currdmap()<<7));
3646 72 }
3647 72 }
3648 2297 }
3649
3650 7118562993 void draw_cmb(BITMAP* dest, int32_t x, int32_t y, int32_t cid, int32_t cset,
3651 bool over, bool transp)
3652 {
3653 7118562993 auto& cmb = combobuf[cid];
3654
2/2
✓ Branch 0 taken 93673 times.
✓ Branch 1 taken 7118469320 times.
7118562993 if(cmb.animflags & AF_EDITOR_ONLY)
3655 93673 return;
3656
2/2
✓ Branch 0 taken 3924435462 times.
✓ Branch 1 taken 3194033858 times.
7118469320 if(over)
3657 {
3658
2/2
✓ Branch 0 taken 841117 times.
✓ Branch 1 taken 3923594345 times.
3924435462 if(cmb.animflags & AF_TRANSPARENT)
3659 841117 transp = !transp;
3660
2/2
✓ Branch 0 taken 328615081 times.
✓ Branch 1 taken 3595820381 times.
3924435462 if(transp)
3661 328615081 overcombotranslucent(dest, x, y, cid, cset, 128);
3662 3595820381 else overcombo(dest, x, y, cid, cset);
3663 3924435462 }
3664 3194033858 else putcombo(dest, x, y, cid, cset);
3665 7118562993 }
3666 7118571441 void draw_cmb_pos(BITMAP* dest, int32_t x, int32_t y, rpos_t rpos, int32_t cid,
3667 int32_t cset, byte layer, bool over, bool transp)
3668 {
3669
2/2
✓ Branch 0 taken 847534117 times.
✓ Branch 1 taken 6271037324 times.
7118571441 if (rpos != rpos_t::None)
3670 {
3671 6271037324 rpos_t plrpos = COMBOPOS_REGION_B(Hero.x+8, Hero.y+8);
3672
2/2
✓ Branch 0 taken 749524 times.
✓ Branch 1 taken 6270287800 times.
6271037324 if (plrpos != rpos_t::None)
3673 {
3674 6270287800 bool dosw = false;
3675
4/4
✓ Branch 0 taken 67998 times.
✓ Branch 1 taken 6270219802 times.
✓ Branch 2 taken 59550 times.
✓ Branch 3 taken 8448 times.
6270287800 if (rpos == hooked_comborpos && (hooked_layerbits & (1<<layer)))
3676 {
3677
1/2
✓ Branch 0 taken 8448 times.
✗ Branch 1 not taken.
8448 if(hooked_undercombos[layer] > -1)
3678 {
3679 draw_cmb(dest, x, y,
3680 hooked_undercombos[layer], hooked_undercombos[layer+7], over, transp);
3681 }
3682 8448 dosw = true;
3683 8448 }
3684
4/4
✓ Branch 0 taken 35593420 times.
✓ Branch 1 taken 6234685932 times.
✓ Branch 2 taken 8448 times.
✓ Branch 3 taken 35584972 times.
6270279352 else if (rpos == plrpos && (hooked_layerbits & (1<<(layer+8))))
3685 {
3686 8448 dosw = true;
3687 8448 }
3688
2/2
✓ Branch 0 taken 6270270904 times.
✓ Branch 1 taken 16896 times.
6270287800 if (dosw)
3689 {
3690
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 16896 times.
✗ Branch 3 not taken.
16896 switch (Hero.switchhookstyle)
3691 {
3692 default: case swPOOF:
3693 break; //Nothing special here
3694 case swFLICKER:
3695 {
3696
2/2
✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 8448 times.
16896 if(abs(Hero.switchhookclk-33)&0b1000)
3697 8448 break; //Drawn this frame
3698 8448 return; //Not drawn this frame
3699 }
3700 case swRISE:
3701 {
3702 //Draw rising up
3703 y -= 8-(abs(Hero.switchhookclk-32)/4);
3704 break;
3705 }
3706 }
3707 8448 }
3708 6270279352 }
3709 6271028876 }
3710
3711 7118562993 draw_cmb(dest, x, y, cid, cset, over, transp);
3712 7118571441 }
3713
3714 // `draw_cmb_pos` only does meaningful work if the combo being drawn is within the bounds of
3715 // the `bmp` bitmap. However, even getting to the point where `puttile16` (for example) knows
3716 // to cull is somewhat expensive. Since it can only draw 16x16 pixels, we can do the equivalent
3717 // culling here by determining the rows/columns that are within the bitmap bounds. This nets
3718 // on the order of ~30 FPS in uncapped mode on my machine, depending on the viewport/region size.
3719 //
3720 // These two inequalities must be true for `draw_cmb_pos` to do anything useful:
3721 //
3722 // -16 < comboPositionX*16 + x < bitmapWidth
3723 // -16 < comboPositionY*16 + y < bitmapHeight
3724 //
3725 // The following start/end values are derived directly from the above.
3726 //
3727 // `x` and `y` are the offsets the combos will be drawn into the bitmap.
3728 44027755 static void get_bounds_for_draw_cmb_calls(BITMAP* bmp, int x, int y, int& start_x, int& end_x, int& start_y, int& end_y)
3729 {
3730 // if (bmp->clip)
3731 // {
3732 // start_x = MAX(0, ceil((bmp->cl - 15 - x) / 16.0));
3733 // end_x = MIN(16, ceil((bmp->cr - x) / 16.0));
3734 // start_y = MAX(0, ceil((bmp->ct - 15 - y) / 16.0));
3735 // end_y = MIN(11, ceil((bmp->cb - y) / 16.0));
3736 // return;
3737 // }
3738
3739
2/2
✓ Branch 0 taken 2404962 times.
✓ Branch 1 taken 41622793 times.
44027755 start_x = MAX(0, ceil((-15 - x) / 16.0));
3740
2/2
✓ Branch 0 taken 2412938 times.
✓ Branch 1 taken 41614817 times.
44027755 end_x = MIN(16, ceil((bmp->w - x) / 16.0));
3741
2/2
✓ Branch 0 taken 42489206 times.
✓ Branch 1 taken 1538549 times.
44027755 start_y = MAX(0, ceil((-15 - y) / 16.0));
3742
2/2
✓ Branch 0 taken 1874535 times.
✓ Branch 1 taken 42153220 times.
44027755 end_y = MIN(11, ceil((bmp->h - y) / 16.0));
3743 44027755 }
3744
3745 195648364 void do_ffc_layer(BITMAP* bmp, int32_t layer, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3746 {
3747
1/2
✓ Branch 0 taken 195648364 times.
✗ Branch 1 not taken.
195648364 if(!show_ffcs) return;
3748 195648364 mapscr* scr = screen_handle.scr;
3749 195648364 mapscr* base_scr = screen_handle.base_scr;
3750
3751 195648364 y += playing_field_offset;
3752
3753 195648364 bool is_overhead = layer == -1000;
3754
2/2
✓ Branch 0 taken 53230064 times.
✓ Branch 1 taken 142418300 times.
195648364 bool is_bg_layer = layer < 0 && !is_overhead;
3755
2/2
✓ Branch 0 taken 35522046 times.
✓ Branch 1 taken 160126318 times.
195648364 int real_layer = is_bg_layer ? abs(layer) : layer;
3756
2/2
✓ Branch 0 taken 195648364 times.
✓ Branch 1 taken 5610067558 times.
5805715922 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3757 {
3758
2/2
✓ Branch 0 taken 217455144 times.
✓ Branch 1 taken 5392612414 times.
5610067558 if (base_scr->ffcs[i].data == 0)
3759 5392612414 continue;
3760
3/4
✓ Branch 0 taken 39536116 times.
✓ Branch 1 taken 177919028 times.
✓ Branch 2 taken 39536116 times.
✗ Branch 3 not taken.
217455144 if (is_bg_layer && base_scr->ffcs[i].layer == layer)
3761 ; // ffc is set negative, skip bg layer flag checks
3762 else
3763 {
3764
4/4
✓ Branch 0 taken 39536089 times.
✓ Branch 1 taken 177919055 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 19768031 times.
217455144 if(real_layer == 2 && (is_bg_layer != XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG)))
3765 19768031 continue;
3766
4/4
✓ Branch 0 taken 39535883 times.
✓ Branch 1 taken 158151230 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 19767825 times.
197687113 else if (real_layer == 3 && (is_bg_layer != XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)))
3767 19767825 continue;
3768
4/4
✓ Branch 0 taken 158156192 times.
✓ Branch 1 taken 19763096 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 138388134 times.
177919288 if (real_layer > -1 && base_scr->ffcs[i].layer != real_layer)
3769 138388134 continue;
3770 }
3771
3772
6/6
✓ Branch 0 taken 3311080 times.
✓ Branch 1 taken 36220074 times.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 3305970 times.
✓ Branch 4 taken 2626 times.
✓ Branch 5 taken 2484 times.
39531154 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3773 2484 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3774
3775 39528670 base_scr->ffcs[i].draw_ffc(bmp, x, y, is_overhead);
3776 39528670 }
3777 195648364 }
3778 177456832 void _do_current_ffc_layer(BITMAP* bmp, int32_t layer)
3779 {
3780
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 177456832 times.
177456832 if(!show_ffcs) return;
3781 359838606 for_every_base_screen_in_region([&](mapscr* base_scr, unsigned int region_scr_x, unsigned int region_scr_y) {
3782 182381774 screen_handle_t handle = {base_scr, base_scr, base_scr->screen, 0};
3783 182381774 do_ffc_layer(bmp, layer, handle, 0, 0);
3784 182381774 });
3785 177456832 }
3786 110478586 void do_scrolling_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3787 {
3788 110478586 mapscr* scr = screen_handle.scr;
3789 110478586 mapscr* base_scr = screen_handle.base_scr;
3790
3791
4/4
✓ Branch 0 taken 69319430 times.
✓ Branch 1 taken 41159156 times.
✓ Branch 2 taken 41159156 times.
✓ Branch 3 taken 110478586 times.
110478586 if (type == -3 || type == -4)
3792 {
3793 82318312 y += playing_field_offset;
3794
3795
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
82318312 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3796 {
3797 if (base_scr->ffcs[i].data == 0)
3798 continue;
3799
3800 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3801 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3802
3803 base_scr->ffcs[i].draw_ffc(bmp, x, y, (type==-4));
3804 }
3805 return;
3806 }
3807
3808 110478586 x -= viewport.x;
3809 110478586 y -= viewport.y - playing_field_offset;
3810
3811 110478586 bool over = true, transp = false;
3812 110478586 int layer = screen_handle.layer;
3813
3814
7/8
✓ Branch 0 taken 86212000 times.
✓ Branch 1 taken 24266586 times.
✓ Branch 2 taken 15025887 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 62898609 times.
✓ Branch 5 taken 23313391 times.
✓ Branch 6 taken 3907230 times.
✓ Branch 7 taken 5333469 times.
110478586 switch(type ? type : layer)
3815 {
3816 case -2: //push blocks
3817
2/2
✓ Branch 0 taken 21739453 times.
✓ Branch 1 taken 41159156 times.
62898609 if (scr)
3818 {
3819
2/2
✓ Branch 0 taken 3826143728 times.
✓ Branch 1 taken 62083257 times.
3862556601 for(int32_t i=0; i<176; i++)
3820 {
3821 3826143728 int32_t mf=scr->sflag[i], mf2 = combobuf[scr->data[i]].flag;
3822
3823
10/10
✓ Branch 0 taken 3825973384 times.
✓ Branch 1 taken 170344 times.
✓ Branch 2 taken 3824496179 times.
✓ Branch 3 taken 1477205 times.
✓ Branch 4 taken 3823862940 times.
✓ Branch 5 taken 633239 times.
✓ Branch 6 taken 53394531 times.
✓ Branch 7 taken 3770468409 times.
✓ Branch 8 taken 100280201 times.
✓ Branch 9 taken 57521370 times.
3869735241 if(mf==mfPUSHUD || mf==mfPUSH4 || mf==mfPUSHED || ((mf>=mfPUSHLR)&&(mf<=mfPUSHRINS))
3824
6/8
✓ Branch 0 taken 3820980291 times.
✓ Branch 1 taken 50511882 times.
✓ Branch 2 taken 3820980291 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3820980291 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 43591513 times.
✓ Branch 7 taken 3777388778 times.
3823862940 || mf2==mfPUSHUD || mf2==mfPUSH4 || mf2==mfPUSHED || ((mf2>=mfPUSHLR)&&(mf2<=mfPUSHRINS)))
3825 {
3826
4/4
✓ Branch 0 taken 5124570 times.
✓ Branch 1 taken 782430 times.
✓ Branch 2 taken 3849 times.
✓ Branch 3 taken 5120721 times.
206467402 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3827 5907000 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3828 5907000 }
3829 3840817148 }
3830 62083257 }
3831 103242413 return;
3832
3833 case -1: //over combo
3834
1/2
✓ Branch 0 taken 23313391 times.
✗ Branch 1 not taken.
23313391 if (scr)
3835 {
3836
2/2
✓ Branch 0 taken 4103156816 times.
✓ Branch 1 taken 23313391 times.
4126470207 for(int32_t i=0; i<176; i++)
3837 {
3838
2/2
✓ Branch 0 taken 4083826896 times.
✓ Branch 1 taken 19329920 times.
4103156816 if(combo_class_buf[combobuf[scr->data[i]].type].overhead)
3839 {
3840
4/4
✓ Branch 0 taken 15574819 times.
✓ Branch 1 taken 3755101 times.
✓ Branch 2 taken 22336 times.
✓ Branch 3 taken 15552483 times.
19329920 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3841 19329920 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3842 19329920 }
3843 4103156816 }
3844 23313391 }
3845 23313391 return;
3846
3847 case 1:
3848 case 4:
3849 case 5:
3850 case 6:
3851
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15025887 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15025887 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3852 {
3853
1/2
✓ Branch 0 taken 15025887 times.
✗ Branch 1 not taken.
15025887 if (scr)
3854 {
3855
2/2
✓ Branch 0 taken 13331185 times.
✓ Branch 1 taken 1694702 times.
15025887 if(base_scr->layeropacity[layer-1]!=255)
3856 1694702 transp = true;
3857 15025887 break;
3858 }
3859 }
3860 return;
3861
3862 case 2:
3863
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3907230 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3907230 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3864 {
3865
1/2
✓ Branch 0 taken 3907230 times.
✗ Branch 1 not taken.
3907230 if (scr)
3866 {
3867
2/2
✓ Branch 0 taken 3670944 times.
✓ Branch 1 taken 236286 times.
3907230 if(base_scr->layeropacity[layer-1]!=255)
3868 236286 transp = true;
3869
3870
2/2
✓ Branch 0 taken 3759775 times.
✓ Branch 1 taken 147455 times.
3907230 if(XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3871 147455 over = false;
3872
3873 3907230 break;
3874 }
3875 }
3876 return;
3877
3878 case 3:
3879
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5333469 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5333469 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3880 {
3881
1/2
✓ Branch 0 taken 5333469 times.
✗ Branch 1 not taken.
5333469 if (scr)
3882 {
3883
2/2
✓ Branch 0 taken 5258193 times.
✓ Branch 1 taken 75276 times.
5333469 if(base_scr->layeropacity[layer-1]!=255)
3884 75276 transp = true;
3885
3886
2/2
✓ Branch 0 taken 36654 times.
✓ Branch 1 taken 237618 times.
5333469 if(XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
3887
2/2
✓ Branch 0 taken 274272 times.
✓ Branch 1 taken 5059197 times.
5333469 && !XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3888 237618 over = false;
3889
3890 5333469 break;
3891 }
3892 }
3893 return;
3894 }
3895
3896 int start_x, end_x, start_y, end_y;
3897 24266586 get_bounds_for_draw_cmb_calls(bmp, x, y, start_x, end_x, start_y, end_y);
3898
2/2
✓ Branch 0 taken 24266586 times.
✓ Branch 1 taken 257467292 times.
281733878 for (int cy = start_y; cy < end_y; cy++)
3899 {
3900
2/2
✓ Branch 0 taken 3897791767 times.
✓ Branch 1 taken 257467292 times.
4155259059 for (int cx = start_x; cx < end_x; cx++)
3901 {
3902 3897791767 int i = cx + cy*16;
3903
4/4
✓ Branch 0 taken 3440940732 times.
✓ Branch 1 taken 456851035 times.
✓ Branch 2 taken 11831072 times.
✓ Branch 3 taken 3429109660 times.
3897791767 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3904 3897791767 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, over, transp);
3905 3897791767 }
3906 257467292 }
3907 69319430 }
3908
3909 279438145 bool lenscheck(mapscr* scr, int layer)
3910 {
3911
4/4
✓ Branch 0 taken 279261573 times.
✓ Branch 1 taken 176572 times.
✓ Branch 2 taken 176572 times.
✓ Branch 3 taken 279438145 times.
279438145 if(layer < 0 || layer > 6) return true;
3912
2/2
✓ Branch 0 taken 259600965 times.
✓ Branch 1 taken 19837180 times.
279438145 if(get_qr(qr_OLD_LENS_LAYEREFFECT))
3913 {
3914
2/2
✓ Branch 0 taken 209719861 times.
✓ Branch 1 taken 49881104 times.
259600965 if(!layer) return true;
3915
8/8
✓ Branch 0 taken 34924333 times.
✓ Branch 1 taken 174795528 times.
✓ Branch 2 taken 258970 times.
✓ Branch 3 taken 34665363 times.
✓ Branch 4 taken 146134 times.
✓ Branch 5 taken 259680 times.
✓ Branch 6 taken 326536 times.
✓ Branch 7 taken 34484961 times.
209719861 if((layer==(int32_t)(scr->lens_layer&7)+1) && ((scr->lens_layer&llLENSSHOWS && !lensclk) || (scr->lens_layer&llLENSHIDES && lensclk)))
3916 586216 return false;
3917 209280489 }
3918 else
3919 {
3920
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19837180 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 19837180 times.
19837180 if((lensclk ? scr->lens_hide : scr->lens_show) & (1<<layer))
3921 return false;
3922 }
3923 229117669 return true;
3924 279261573 }
3925
3926 165091049 void do_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3927 {
3928 165091049 bool showlayer = true;
3929 165091049 mapscr* base_scr = screen_handle.base_scr;
3930 165091049 int layer = screen_handle.layer;
3931
2/2
✓ Branch 0 taken 46548317 times.
✓ Branch 1 taken 118542732 times.
165091049 int target = type ? type : layer;
3932
3/4
✓ Branch 0 taken 118542732 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22465475 times.
✓ Branch 3 taken 24082842 times.
165091049 switch(target)
3933 {
3934 case -2:
3935
1/2
✓ Branch 0 taken 22465475 times.
✗ Branch 1 not taken.
22465475 if(!show_layer_push)
3936 showlayer = false;
3937 22465475 break;
3938
3939 case -1:
3940
1/2
✓ Branch 0 taken 24082842 times.
✗ Branch 1 not taken.
24082842 if(!show_layer_over)
3941 showlayer = false;
3942 24082842 break;
3943
3944 case 1: case 2: case 3:
3945 case 4: case 5: case 6:
3946 118542732 showlayer = show_layers[target];
3947 118542732 break;
3948 }
3949
3950
2/2
✓ Branch 0 taken 46548317 times.
✓ Branch 1 taken 118542732 times.
165091049 if(!type)
3951 {
3952
2/2
✓ Branch 0 taken 118406534 times.
✓ Branch 1 taken 136198 times.
118542732 if(!lenscheck(base_scr,layer))
3953 136198 showlayer = false;
3954 118542732 }
3955
3956
2/2
✓ Branch 0 taken 136198 times.
✓ Branch 1 taken 164954851 times.
165091049 if(showlayer)
3957 {
3958
6/6
✓ Branch 0 taken 69411378 times.
✓ Branch 1 taken 95543473 times.
✓ Branch 2 taken 24358534 times.
✓ Branch 3 taken 45052844 times.
✓ Branch 4 taken 91948 times.
✓ Branch 5 taken 24266586 times.
164954851 if (screen_handle.scr && (type || !(base_scr->hidelayers & (1 << (layer)))))
3959 {
3960 69319430 do_scrolling_layer(bmp, type, screen_handle, x, y);
3961
4/4
✓ Branch 0 taken 24266586 times.
✓ Branch 1 taken 45052844 times.
✓ Branch 2 taken 22269756 times.
✓ Branch 3 taken 1996830 times.
69319430 if(!type && !get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
3962
2/2
✓ Branch 0 taken 1996254 times.
✓ Branch 1 taken 576 times.
1997406 if(mblock2.draw(bmp,layer))
3963 576 do_primitives(bmp, SPLAYER_MOVINGBLOCK);
3964 69319430 }
3965 164954851 }
3966 165091049 }
3967
3968 106997110 void do_layer_primitives(BITMAP *bmp, int32_t layer)
3969 {
3970 106997110 bool showlayer = true;
3971
3972
2/4
✓ Branch 0 taken 106997110 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 106997110 times.
106997110 if(layer >= 0 && layer <= 6)
3973 {
3974 106997110 showlayer = show_layers[layer];
3975
3976
2/2
✓ Branch 0 taken 106870508 times.
✓ Branch 1 taken 126602 times.
106997110 if(!lenscheck(origin_scr,layer))
3977 126602 showlayer = false;
3978 106997110 }
3979
3980
2/2
✓ Branch 0 taken 126602 times.
✓ Branch 1 taken 106870508 times.
106997110 if (showlayer)
3981 106870508 do_primitives(bmp, layer);
3982 106997110 }
3983
3984 // Called by do_walkflags
3985 void put_walkflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
3986 {
3987 newcombo const &c = combobuf[cmbdat];
3988
3989 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3990
3991 int32_t xx = x-xofs;
3992 int32_t yy = y+playing_field_offset-yofs;
3993
3994 int32_t bridgedetected = 0;
3995
3996 for(int32_t i=0; i<4; i++)
3997 {
3998 int32_t tx=((i&2)<<2)+xx - viewport.x;
3999 int32_t ty=((i&1)<<3)+yy - viewport.y;
4000 int32_t tx2=((i&2)<<2)+x - viewport.x;
4001 int32_t ty2=((i&1)<<3)+y - viewport.y;
4002 for (int32_t j = lyr-1; j <= 1; j++)
4003 {
4004 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4005 {
4006 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && !_walkflag_layer(tx2,ty2,j))
4007 {
4008 bridgedetected |= (1<<i);
4009 }
4010 }
4011 else
4012 {
4013 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && _effectflag_layer(tx2,ty2,j))
4014 {
4015 bridgedetected |= (1<<i);
4016 }
4017 }
4018 }
4019 if ((bridgedetected & (1<<i)))
4020 {
4021 if (i >= 3) break;
4022 else continue;
4023 }
4024 bool doladdercheck = true;
4025
4026 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4027 {
4028 for(int32_t k=0; k<8; k+=2)
4029 for(int32_t j=0; j<8; j+=2)
4030 if(((k+j)/2)%2)
4031 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,makecol(85,85,255));
4032 }
4033 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4034 {
4035 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4036 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4037 rectfill(dest,tx,ty,tx+7,ty+7,makecol(85,85,255));
4038 else rectfill(dest,tx,ty,tx+7,ty+7,makecol(170,170,170));
4039 }
4040
4041 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4042 {
4043 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4044 {
4045 for(int32_t k=0; k<8; k+=2)
4046 for(int32_t j=0; j<8; j+=2)
4047 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,((k+j)/2)%2 ? makecol(165,105,8) : makecol(170,170,170));
4048 }
4049 else
4050 {
4051 int32_t color = makecol(178,36,36);
4052
4053 if(isstepable(cmbdat)&& (!doladdercheck))
4054 color=makecol(165,105,8);
4055 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4056 color=makecol(170,170,170);
4057
4058 rectfill(dest,tx,ty,tx+7,ty+7,color);
4059 }
4060 }
4061 }
4062
4063 // Draw damage combos
4064 bool dmg = combo_class_buf[combobuf[MAPCOMBO2(-1,xx,yy)].type].modify_hp_amount
4065 || combo_class_buf[combobuf[MAPCOMBO2(0,xx,yy)].type].modify_hp_amount
4066 || combo_class_buf[combobuf[MAPCOMBO2(1,xx,yy)].type].modify_hp_amount;
4067
4068 if(dmg)
4069 {
4070 int32_t color = makecol(255,255,0);
4071 if (bridgedetected <= 0)
4072 {
4073 for(int32_t k=0; k<16; k+=2)
4074 for(int32_t j=0; j<16; j+=2)
4075 if(((k+j)/2)%2)
4076 {
4077 int32_t x0 = x - viewport.x;
4078 int32_t y0 = y - viewport.y;
4079 rectfill(dest,x0+k,y0+j,x0+k+1,y0+j+1,color);
4080 }
4081 }
4082 else
4083 {
4084 for(int32_t i=0; i<4; i++)
4085 {
4086 if (!(bridgedetected & (1<<i)))
4087 {
4088 int32_t tx=((i&2)<<2)+x - viewport.x;
4089 int32_t ty=((i&1)<<3)+y - viewport.y;
4090 for(int32_t k=0; k<8; k+=2)
4091 for(int32_t j=0; j<8; j+=2)
4092 if((k+j)%4 < 2) rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,color);
4093 }
4094 }
4095 }
4096 }
4097 }
4098 static void put_walkflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4099 {
4100 ALLEGRO_COLOR col_solid = al_map_rgba(178,36,36,info_opacity);
4101 ALLEGRO_COLOR col_water1 = al_map_rgba(85,85,255,info_opacity);
4102 ALLEGRO_COLOR col_lhook = al_map_rgba(170,170,170,info_opacity);
4103 ALLEGRO_COLOR col_stepable = al_map_rgba(165,105,8,info_opacity);
4104 ALLEGRO_COLOR col_dmg = al_map_rgba(255,255,0,info_opacity);
4105 newcombo const &c = combobuf[cmbdat];
4106
4107 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
4108
4109 int32_t xx = x-viewport.x;
4110 int32_t yy = y+playing_field_offset-viewport.y;
4111
4112 int32_t bridgedetected = 0;
4113
4114 // Draw damage combos
4115 bool dmg = combo_class_buf[c.type].modify_hp_amount;
4116
4117 for(int32_t i=0; i<4; i++)
4118 {
4119 int32_t tx=((i&2)<<2)+xx;
4120 int32_t ty=((i&1)<<3)+yy;
4121 int32_t tx2=((i&2)<<2)+x;
4122 int32_t ty2=((i&1)<<3)+y;
4123 for (int32_t m = lyr-1; m <= 1; m++)
4124 {
4125 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4126 {
4127 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && !_walkflag_layer(tx2, ty2, m))
4128 {
4129 bridgedetected |= (1<<i);
4130 }
4131 }
4132 else
4133 {
4134 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && _effectflag_layer(tx2, ty2, m))
4135 {
4136 bridgedetected |= (1<<i);
4137 }
4138 }
4139 }
4140 if ((bridgedetected & (1<<i)))
4141 continue;
4142 bool doladdercheck = true;
4143
4144 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4145 {
4146 for(int32_t k=0; k<8; k+=2)
4147 for(int32_t j=0; j<8; j+=2)
4148 if(((k+j)/2)%2)
4149 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_water1);
4150 }
4151 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4152 {
4153 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4154 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4155 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_water1);
4156 else al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_lhook);
4157 }
4158
4159 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4160 {
4161 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4162 {
4163 for(int32_t k=0; k<8; k+=2)
4164 for(int32_t j=0; j<8; j+=2)
4165 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,((k+j)/2)%2 ? col_stepable : col_lhook);
4166 }
4167 else
4168 {
4169 ALLEGRO_COLOR* color = &col_solid;
4170
4171 if(isstepable(cmbdat)&& (!doladdercheck))
4172 color=&col_stepable;
4173 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4174 color=&col_lhook;
4175
4176 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,*color);
4177 }
4178 }
4179
4180 if(dmg)
4181 {
4182 for(int32_t k=0; k<8; k+=2)
4183 for(int32_t j=0; j<8; j+=2)
4184 if((k+j)%4 < 2) al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_dmg);
4185 }
4186 }
4187 }
4188
4189 void put_effectflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
4190 {
4191 newcombo const &c = combobuf[cmbdat];
4192
4193 int32_t xx = x-xofs-viewport.x;
4194 int32_t yy = y+playing_field_offset-yofs-viewport.y;
4195
4196 for(int32_t i=0; i<4; i++)
4197 {
4198 int32_t tx=((i&2)<<2)+xx;
4199 int32_t ty=((i&1)<<3)+yy;
4200
4201 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4202 {
4203 int32_t color = vc(10);
4204
4205 rectfill(dest,tx,ty,tx+7,ty+7,color);
4206 }
4207 }
4208 }
4209 static void put_effectflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4210 {
4211 ALLEGRO_COLOR col_eff = al_map_rgba(85,255,85,info_opacity);
4212 newcombo const &c = combobuf[cmbdat];
4213
4214 int32_t xx = x-viewport.x;
4215 int32_t yy = y+playing_field_offset-viewport.y;
4216
4217 for(int32_t i=0; i<4; i++)
4218 {
4219 int32_t tx=((i&2)<<2)+xx;
4220 int32_t ty=((i&1)<<3)+yy;
4221
4222 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4223 {
4224 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_eff);
4225 }
4226 }
4227 }
4228
4229 void draw_ladder_platform(BITMAP* dest, int32_t x, int32_t y, int32_t c)
4230 {
4231 for(auto cx = 0; cx < 256; cx += 16)
4232 {
4233 for(auto cy = 0; cy < 176; cy += 16)
4234 {
4235 if(isSVLadder(cx,cy))
4236 {
4237 auto nx = cx+x, ny = cy+y;
4238 if(cy && !isSVLadder(cx,cy-16))
4239 line(dest,nx,ny,nx+15,ny,c);
4240 rectfill(dest,nx,ny,nx+3,ny+15,c);
4241 rectfill(dest,nx+12,ny,nx+15,ny+15,c);
4242 rectfill(dest,nx+4,ny+2,nx+11,ny+5,c);
4243 rectfill(dest,nx+4,ny+10,nx+11,ny+13,c);
4244 }
4245 else if(isSVPlatform(cx,cy))
4246 {
4247 line(dest,cx+x,cy+y,cx+x+15,cy+y,c);
4248 }
4249 }
4250 }
4251 }
4252 void draw_ladder_platform_a5(int32_t x, int32_t y, ALLEGRO_COLOR c)
4253 {
4254 for(auto cx = 0; cx < 256; cx += 16)
4255 {
4256 for(auto cy = 0; cy < 176; cy += 16)
4257 {
4258 if(isSVLadder(cx,cy))
4259 {
4260 auto nx = cx+x, ny = cy+y;
4261 if(cy && !isSVLadder(cx,cy-16))
4262 al_draw_line(nx,ny,nx+15,ny,c,1);
4263 al_draw_filled_rectangle(nx,ny,nx+4,ny+16,c);
4264 al_draw_filled_rectangle(nx+12,ny,nx+16,ny+16,c);
4265 al_draw_filled_rectangle(nx+4,ny+2,nx+12,ny+6,c);
4266 al_draw_filled_rectangle(nx+4,ny+10,nx+12,ny+14,c);
4267 }
4268 else if(isSVPlatform(cx,cy))
4269 {
4270 al_draw_line(cx+x,cy+y,cx+x+15,cy+y,c,1);
4271 }
4272 }
4273 }
4274 }
4275
4276 // Walkflags L4 cheat
4277 void do_walkflags(const screen_handles_t& screen_handles, int32_t x, int32_t y)
4278 {
4279 if (!show_walkflags)
4280 return;
4281
4282 start_info_bmp();
4283
4284 mapscr* scr = screen_handles[0].scr;
4285 for(int32_t i=0; i<176; i++)
4286 {
4287 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4288 }
4289
4290 for(int32_t k=0; k<2; k++)
4291 {
4292 scr = screen_handles[k + 1].scr;
4293
4294 if (scr)
4295 {
4296 for(int32_t i=0; i<176; i++)
4297 {
4298 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], k%2+1);
4299 }
4300 }
4301 }
4302
4303 end_info_bmp();
4304 }
4305
4306 void do_walkflags(int32_t x, int32_t y)
4307 {
4308 if (!show_walkflags)
4309 return;
4310
4311 x += -viewport.x;
4312 y += playing_field_offset - viewport.y;
4313
4314 start_info_bmp();
4315
4316 draw_ladder_platform_a5(x,y,al_map_rgba(165,105,8,info_opacity));
4317 draw_solid_objects_a5(x,y,al_map_rgba(178,36,36,info_opacity));
4318 draw_slopes_a5(x,y,al_map_rgba(255,85,255,info_opacity));
4319
4320 end_info_bmp();
4321 }
4322
4323 // Effectflags L4 cheat
4324 void do_effectflags(mapscr* scr, int32_t x, int32_t y)
4325 {
4326 if(show_effectflags)
4327 {
4328 start_info_bmp();
4329
4330 for(int32_t i=0; i<176; i++)
4331 {
4332 put_effectflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4333 }
4334
4335 end_info_bmp();
4336 }
4337 }
4338
4339 400489 void calc_darkroom_combos(mapscr* scr, int offx, int offy)
4340 {
4341 400489 int map = scr->map;
4342 400489 int screen = scr->screen;
4343
4344
2/2
✓ Branch 0 taken 2803423 times.
✓ Branch 1 taken 400489 times.
3203912 for(int32_t lyr = 0; lyr < 7; ++lyr)
4345 {
4346 2803423 mapscr* scr = get_scr_layer(map, screen, lyr);
4347
2/2
✓ Branch 0 taken 1829718 times.
✓ Branch 1 taken 973705 times.
2803423 if (!scr->is_valid()) continue;
4348
4349
2/2
✓ Branch 0 taken 322030368 times.
✓ Branch 1 taken 1829718 times.
323860086 for(int32_t q = 0; q < 176; ++q)
4350 {
4351 322030368 newcombo const& cmb = combobuf[scr->data[q]];
4352
2/2
✓ Branch 0 taken 320498295 times.
✓ Branch 1 taken 1532073 times.
322030368 if(cmb.type == cTORCH)
4353 {
4354 1532073 do_torch_combo(cmb, COMBOX(q)+8+offx, COMBOY(q)+8+offy, darkscr_bmp);
4355 1532073 }
4356 322030368 }
4357 1829718 }
4358 400489 }
4359
4360 400489 void calc_darkroom_ffcs(mapscr* scr, int offx, int offy)
4361 {
4362 400489 word c = scr->numFFC();
4363
2/2
✓ Branch 0 taken 704965 times.
✓ Branch 1 taken 400489 times.
1105454 for(int q = 0; q < c; ++q)
4364 {
4365 704965 newcombo const& cmb = combobuf[scr->ffcs[q].data];
4366
2/2
✓ Branch 0 taken 690157 times.
✓ Branch 1 taken 14808 times.
704965 if(cmb.type == cTORCH)
4367 {
4368 14808 int cx = scr->ffcs[q].x.getInt()+(scr->ffEffectWidth(q)/2)+offx;
4369 14808 int cy = (scr->ffcs[q].y.getInt())+(scr->ffEffectHeight(q)/2)+offy;
4370 14808 do_torch_combo(cmb, cx, cy, darkscr_bmp);
4371 14808 }
4372 704965 }
4373 400489 }
4374
4375 struct nearby_screen_t
4376 {
4377 int screen;
4378 int offx;
4379 int offy;
4380 screen_handles_t screen_handles;
4381 };
4382 typedef std::vector<nearby_screen_t> nearby_screens_t;
4383
4384 16075312 static nearby_screens_t get_nearby_screens_non_scrolling_region()
4385 {
4386 16075312 nearby_screens_t nearby_screens;
4387
4388 16075312 mapscr* base_scr = origin_scr;
4389
1/2
✓ Branch 0 taken 16075312 times.
✗ Branch 1 not taken.
16075312 auto& nearby_screen = nearby_screens.emplace_back();
4390 16075312 nearby_screen.screen = cur_screen;
4391
1/2
✓ Branch 0 taken 16075312 times.
✗ Branch 1 not taken.
16075312 nearby_screen.screen_handles = create_screen_handles(base_scr);
4392
4393 16075312 return nearby_screens;
4394
1/2
✓ Branch 0 taken 16075312 times.
✗ Branch 1 not taken.
16075312 }
4395
4396 48296 static nearby_screens_t get_nearby_screens_scrolling_region()
4397 {
4398 48296 nearby_screens_t nearby_screens;
4399
4400
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x0 = viewport.left() / 256;
4401
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x1 = (viewport.right() - 1) / 256;
4402
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y0 = viewport.top() / 176;
4403
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y1 = (viewport.bottom() - 1) / 176;
4404
4405
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x0 = std::clamp(screens_x0, 0, 15);
4406
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x1 = std::clamp(screens_x1, 0, 15);
4407
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y0 = std::clamp(screens_y0, 0, 8);
4408
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y1 = std::clamp(screens_y1, 0, 8);
4409
4410
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 79928 times.
128224 for (int x = screens_x0; x <= screens_x1; x++)
4411 {
4412
2/2
✓ Branch 0 taken 169672 times.
✓ Branch 1 taken 79928 times.
249600 for (int y = screens_y0; y <= screens_y1; y++)
4413 {
4414 169672 int screen = cur_screen + x + y*16;
4415
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!is_in_current_region(screen)) continue;
4416
4417
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 mapscr* base_scr = get_scr(screen);
4418
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!base_scr->is_valid()) continue;
4419
4420
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
4421
4422
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto& nearby_screen = nearby_screens.emplace_back();
4423 169672 nearby_screen.screen = screen;
4424 169672 nearby_screen.offx = offx;
4425 169672 nearby_screen.offy = offy;
4426
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 nearby_screen.screen_handles = create_screen_handles(base_scr);
4427 169672 }
4428 79928 }
4429
4430 48296 return nearby_screens;
4431
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 }
4432
4433 3658 static nearby_screens_t get_nearby_screens_smooth_maze()
4434 {
4435 3658 nearby_screens_t nearby_screens;
4436
4437
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x0 = viewport.left() / 256;
4438
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x1 = (viewport.right() - 1) / 256;
4439
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y0 = viewport.top() / 176;
4440
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y1 = (viewport.bottom() - 1) / 176;
4441
4442
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.left() < 0) screens_x0--;
4443
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.top() < 0) screens_y0--;
4444
4445
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 7308 times.
10966 for (int x = screens_x0; x <= screens_x1; x++)
4446 {
4447
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 7308 times.
25908 for (int y = screens_y0; y <= screens_y1; y++)
4448 {
4449 18600 int screen = -1;
4450 mapscr* base_scr;
4451 int offx, offy;
4452
4453 18600 mapscr* maze_scr = maze_state.scr;
4454 18600 int maze_screen = maze_scr->screen;
4455
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_x = get_region_relative_dx(maze_screen);
4456
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_y = get_region_relative_dy(maze_screen);
4457 18600 int maze_screen_dx = x - maze_screen_x;
4458 18600 int maze_screen_dy = y - maze_screen_y;
4459 18600 int exitdir = maze_scr->exitdir;
4460
4461 bool should_draw_maze_screen;
4462
2/2
✓ Branch 0 taken 9052 times.
✓ Branch 1 taken 9548 times.
18600 if (maze_state.lost)
4463 {
4464 9548 should_draw_maze_screen = true;
4465 9548 }
4466 else
4467 {
4468 9052 should_draw_maze_screen = true;
4469
4/6
✓ Branch 0 taken 9052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6844 times.
✓ Branch 3 taken 2208 times.
✓ Branch 4 taken 6844 times.
✗ Branch 5 not taken.
9052 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != exitdir && XY_DELTA_TO_DIR(0, maze_screen_dy) != exitdir;
4470
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 5202 times.
9052 if (maze_state.enter_dir != dir_invalid)
4471
4/6
✓ Branch 0 taken 3850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3304 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 3304 times.
✗ Branch 5 not taken.
3850 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != maze_state.enter_dir && XY_DELTA_TO_DIR(0, maze_screen_dy) != maze_state.enter_dir;
4472 }
4473
4474
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (should_draw_maze_screen)
4475 {
4476 16048 screen = maze_state.scr->screen;
4477 16048 base_scr = maze_state.scr;
4478
1/2
✓ Branch 0 taken 16048 times.
✗ Branch 1 not taken.
16048 std::tie(offx, offy) = translate_screen_coordinates_to_world(cur_screen + x + y*16);
4479 16048 }
4480
4481
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (screen == -1)
4482 {
4483 2552 screen = cur_screen + x + y*16;
4484
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!is_in_current_region(screen)) continue;
4485
4486
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 base_scr = get_scr(screen);
4487
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!base_scr->is_valid()) continue;
4488
4489
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 std::tie(offx, offy) = translate_screen_coordinates_to_world(screen);
4490 2552 }
4491
4492
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 auto& nearby_screen = nearby_screens.emplace_back();
4493 18600 nearby_screen.screen = screen;
4494 18600 nearby_screen.offx = offx;
4495 18600 nearby_screen.offy = offy;
4496
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 nearby_screen.screen_handles = create_screen_handles(base_scr);
4497 18600 }
4498 7308 }
4499
4500 3658 return nearby_screens;
4501
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 }
4502
4503 16127266 static nearby_screens_t get_nearby_screens()
4504 {
4505
4/4
✓ Branch 0 taken 9214 times.
✓ Branch 1 taken 16118052 times.
✓ Branch 2 taken 3658 times.
✓ Branch 3 taken 5556 times.
16127266 if (maze_state.active && maze_state.loopy)
4506 3658 return get_nearby_screens_smooth_maze();
4507
4508
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 16075312 times.
16123608 if (is_in_scrolling_region())
4509 48296 return get_nearby_screens_scrolling_region();
4510
4511 16075312 return get_nearby_screens_non_scrolling_region();
4512 16127266 }
4513
4514 209882207 static void for_every_nearby_screen(const nearby_screens_t& nearby_screens, const std::function <void (screen_handles_t, int, int, int)>& fn)
4515 {
4516
2/2
✓ Branch 0 taken 211666809 times.
✓ Branch 1 taken 209882207 times.
421549016 for (auto& nearby_screen : nearby_screens)
4517 211666809 fn(nearby_screen.screen_handles, nearby_screen.screen, nearby_screen.offx, nearby_screen.offy);
4518 209882207 }
4519
4520 145229906 static void draw_msgstr(byte layer, BITMAP* dest = nullptr)
4521 {
4522
2/2
✓ Branch 0 taken 32296004 times.
✓ Branch 1 taken 112933902 times.
145229906 if(layer != msgstr_layer) return;
4523
2/2
✓ Branch 0 taken 16126482 times.
✓ Branch 1 taken 16169522 times.
32296004 if(!dest) dest = framebuf;
4524
4525
2/2
✓ Branch 0 taken 1456533 times.
✓ Branch 1 taken 30839471 times.
32296004 if(!(msg_bg_display_buf->clip))
4526 {
4527 1456533 blit_msgstr_bg(dest,0,0,0,playing_field_offset,256,176);
4528 1456533 }
4529
4530
2/2
✓ Branch 0 taken 1456533 times.
✓ Branch 1 taken 30839471 times.
32296004 if(!(msg_portrait_display_buf->clip))
4531 {
4532 1456533 blit_msgstr_prt(dest,0,0,0,playing_field_offset,256,176);
4533 1456533 }
4534
4535
2/2
✓ Branch 0 taken 1483347 times.
✓ Branch 1 taken 30812657 times.
32296004 if(!(msg_txt_display_buf->clip))
4536 {
4537 1483347 blit_msgstr_fg(dest,0,0,0,playing_field_offset,256,176);
4538 1483347 }
4539 145229906 }
4540
4541 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y);
4542
4543 64509064 static void set_draw_screen_clip(BITMAP* bmp)
4544 {
4545 64509064 set_clip_rect(bmp, draw_screen_clip_rect_x1, draw_screen_clip_rect_y1, draw_screen_clip_rect_x2, draw_screen_clip_rect_y2);
4546 64509064 }
4547
4548 17580 static void draw_sprites(BITMAP* dest, set<sprite*, SpriteSorter>& sprite_set, set<sprite*, SpriteSorter>::iterator& it, word upto_z)
4549 {
4550 17580 bool checkz = upto_z != word(-1); // max value represents "infinity" height
4551
6/6
✓ Branch 0 taken 11145 times.
✓ Branch 1 taken 6435 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 6275 times.
✓ Branch 4 taken 12905 times.
✓ Branch 5 taken 4675 times.
17580 if(it == sprite_set.end() || (checkz && (*it)->total_z() >= upto_z))
4552 12905 return; // no sprites to draw remaining
4553 // Just clips sprites if in a repeating, smooth maze.
4554
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 bool do_clip = maze_state.active && maze_state.loopy;
4555
4556
4557
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 if(do_clip)
4558 {
4559 int maze_screen = maze_state.scr->screen;
4560 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4561 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4562 }
4563
6/6
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 32443 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 32283 times.
✓ Branch 4 taken 4675 times.
✓ Branch 5 taken 30698 times.
67816 while(it != sprite_set.end() && (!checkz || (*it)->total_z() < upto_z))
4564 {
4565 30698 sprite* spr = *it;
4566
2/2
✓ Branch 0 taken 27768 times.
✓ Branch 1 taken 2930 times.
30698 if(spr == &Hero) // Draw the Hero
4567 {
4568 2930 decorations.draw2(dest,true);
4569 2930 Hero.draw(dest);
4570 2930 decorations.draw(dest,true);
4571
4572 // Draw enemies holding the Hero directly above the Hero
4573
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 for(int32_t i=0; i<guys.Count(); i++)
4574 {
4575 if(((enemy*)guys.spr(i))->type == eeWALK)
4576 if(((eStalfos*)guys.spr(i))->hashero)
4577 guys.spr(i)->draw(dest);
4578 else if(((enemy*)guys.spr(i))->type == eeWALLM)
4579 if(((eWallM*)guys.spr(i))->hashero)
4580 guys.spr(i)->draw(dest);
4581 }
4582 2930 }
4583
2/2
✓ Branch 0 taken 24838 times.
✓ Branch 1 taken 2930 times.
27768 else if(spr == &mblock2) // Draw the moving pushblock
4584 {
4585 2930 mblock2.draw(dest, -1);
4586 2930 do_primitives(dest, SPLAYER_MOVINGBLOCK);
4587 2930 }
4588
2/4
✓ Branch 0 taken 24838 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24838 times.
24838 else if(enemy* e = dynamic_cast<enemy*>(spr))
4589 {
4590 e->draw(dest);
4591 e->draw2(dest); // used specifically for eGleeok/esGleeok
4592 }
4593 24838 else spr->draw(dest);
4594 30698 ++it;
4595 }
4596
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 if(do_clip)
4597 clear_clip_rect(dest);
4598 17580 }
4599
4600 11991 static void draw_high_darkness(BITMAP* dest)
4601 {
4602 11991 do_primitives(dest, SPLAYER_DARKROOM_UNDER);
4603 11991 set_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
4604
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
4605 {
4606 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
4607 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
4608 }
4609
4610 11991 color_map = &trans_table2;
4611
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
4612 {
4613 draw_trans_sprite(dest, darkscr_bmp, 0, 0);
4614 if(get_qr(qr_NEWDARK_TRANS_STACKING))
4615 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
4616 }
4617 else
4618 {
4619 11991 masked_blit(darkscr_bmp, dest, 0, 0, 0, 0, dest->w, dest->h);
4620 11991 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
4621 }
4622 11991 color_map = &trans_table;
4623
4624 11991 set_clip_rect(dest, 0, 0, dest->w, dest->h);
4625 11991 do_primitives(dest, SPLAYER_DARKROOM_OVER);
4626 11991 }
4627
4628 16169522 static void draw_screen_post_passive_subscreen(BITMAP* dest, bool any_dark)
4629 {
4630 16169522 draw_msgstr(6, dest);
4631
4632
1/2
✓ Branch 0 taken 16169522 times.
✗ Branch 1 not taken.
16169522 if (get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
4633 draw_msgstr(6, dest);
4634
4635
6/6
✓ Branch 0 taken 1899309 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 447626 times.
✓ Branch 3 taken 1451683 times.
✓ Branch 4 taken 435635 times.
✓ Branch 5 taken 11991 times.
16169522 if (get_qr(qr_NEW_DARKROOM) && !get_qr(qr_NEWDARK_L6) && any_dark)
4636 11991 draw_high_darkness(dest);
4637
4638 16169522 _do_current_ffc_layer(dest, 7);
4639 16169522 draw_msgstr(7, dest);
4640 16169522 }
4641
4642 // Draws to framebuf.
4643 //
4644 // But if drawPassiveSubscreenSeparate is true: framebuf_no_passive_subscreen will also contain all
4645 // draws excluding the passive subscreen.
4646 16127266 void draw_screen(bool showhero, bool runGeneric, bool drawPassiveSubscreenSeparate)
4647 {
4648 16127266 bool classic_draw = get_qr(qr_CLASSIC_DRAWING_ORDER);
4649 16127266 clear_info_bmp();
4650
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16127266 times.
16127266 if((GameFlags & (GAMEFLAG_SCRIPTMENU_ACTIVE|GAMEFLAG_F6SCRIPT_ACTIVE))!=0)
4651 {
4652 FFCore.doScriptMenuDraws();
4653 return;
4654 }
4655
4656
2/2
✓ Branch 0 taken 613373 times.
✓ Branch 1 taken 15513893 times.
16127266 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_PRE_DRAW);
4657
4658 16127266 BITMAP* dest = framebuf;
4659 16127266 clear_bitmap(dest);
4660 16127266 clear_clip_rect(dest);
4661
4662 16127266 int32_t cmby2=0;
4663
4664 // Draw some background layers
4665 16127266 clear_bitmap(scrollbuf);
4666
4667 16127266 auto nearby_screens = get_nearby_screens();
4668
4669
2/2
✓ Branch 0 taken 16124336 times.
✓ Branch 1 taken 2930 times.
16127266 if (!classic_draw)
4670 {
4671
2/2
✓ Branch 0 taken 11720 times.
✓ Branch 1 taken 2930 times.
14650 for (int layer = -7; layer <= -4; ++layer)
4672 {
4673
1/2
✓ Branch 0 taken 11720 times.
✗ Branch 1 not taken.
11720 _do_current_ffc_layer(scrollbuf, layer);
4674
2/4
✓ Branch 0 taken 11720 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11720 times.
11720 if (script_drawing_commands.is_dirty(layer))
4675 do_primitives(scrollbuf, layer);
4676 11720 }
4677 2930 }
4678
4679 // Handle layer 2/3 possibly being background layers.
4680
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16124336 times.
16127266 if (classic_draw) // weird ordering (-3 > -2)
4681 {
4682
1/2
✓ Branch 0 taken 16124336 times.
✗ Branch 1 not taken.
32384990 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4683 16260654 mapscr* base_scr = screen_handles[0].base_scr;
4684
2/2
✓ Branch 0 taken 16118533 times.
✓ Branch 1 taken 142121 times.
16260654 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4685 142121 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4686 16260654 });
4687
4688 16124336 bool l2bg = XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG);
4689
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 15982215 times.
16124336 if (l2bg)
4690 {
4691
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 do_layer_primitives(scrollbuf, 2);
4692
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 particles.draw(scrollbuf, true, 2);
4693 142121 }
4694
1/2
✓ Branch 0 taken 16124336 times.
✗ Branch 1 not taken.
16124336 _do_current_ffc_layer(scrollbuf, -2);
4695
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 15982215 times.
16124336 if (l2bg)
4696
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 draw_msgstr(2, scrollbuf);
4697 16124336 }
4698
4699
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
32390850 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4700 16263584 mapscr* base_scr = screen_handles[0].base_scr;
4701
2/2
✓ Branch 0 taken 16029020 times.
✓ Branch 1 taken 234564 times.
16263584 if (XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4702 234564 do_layer(scrollbuf, 0, screen_handles[3], offx, offy);
4703 16263584 });
4704
4705
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 15892702 times.
16127266 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4706 {
4707
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 do_layer_primitives(scrollbuf, 3);
4708
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 particles.draw(scrollbuf, true, 3);
4709 234564 }
4710
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 _do_current_ffc_layer(scrollbuf, -3);
4711
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 15892702 times.
16127266 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4712
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 draw_msgstr(3, scrollbuf);
4713
4714
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16124336 times.
16127266 if (!classic_draw)
4715 {
4716
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -3);
4717 // Actually use proper ordering (-3 < -2)
4718
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
5860 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4719 2930 mapscr* base_scr = screen_handles[0].base_scr;
4720
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4721 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4722 2930 });
4723
4724 2930 bool l2bg = XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG);
4725
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if (l2bg)
4726 {
4727 do_layer_primitives(scrollbuf, 2);
4728 particles.draw(scrollbuf, true, 2);
4729 }
4730
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 _do_current_ffc_layer(scrollbuf, -2);
4731
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if (l2bg)
4732 draw_msgstr(2, scrollbuf);
4733
4734
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -2);
4735
4736
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 _do_current_ffc_layer(scrollbuf, -1);
4737
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -1);
4738 2930 }
4739
4740 // Draw the main combo screens ("layer 0").
4741
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
32390850 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4742 16263584 mapscr* base_scr = screen_handles[0].base_scr;
4743
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16263584 times.
16263584 if (lenscheck(base_scr, 0))
4744 {
4745 16263584 putscr(base_scr, scrollbuf, offx, offy + playing_field_offset);
4746 16263584 }
4747 16263584 });
4748
4749
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16127266 times.
16127266 if (lenscheck(hero_scr, 0))
4750 {
4751
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15661217 times.
16127266 if(!get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4752
3/4
✓ Branch 0 taken 466049 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4136 times.
✓ Branch 3 taken 461913 times.
470185 if(mblock2.draw(scrollbuf,0))
4753
1/2
✓ Branch 0 taken 4136 times.
✗ Branch 1 not taken.
4136 do_primitives(scrollbuf, SPLAYER_MOVINGBLOCK);
4754 16127266 }
4755
4756 // Lens hints, then primitives, then particles.
4757
6/10
✓ Branch 0 taken 16117237 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 16117237 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 16117237 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5876 times.
✓ Branch 9 taken 4153 times.
16127266 if((lensclk || (get_debug() && zc_getkey(KEY_L))) && !get_qr(qr_OLDLENSORDER))
4758 {
4759
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 draw_lens_under(scrollbuf, false);
4760
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4761 5876 }
4762
4763
2/4
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16127266 times.
✗ Branch 3 not taken.
16127266 if(show_layers[0] && lenscheck(hero_scr,0))
4764
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 do_primitives(scrollbuf, 0);
4765
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 particles.draw(scrollbuf, true, 0);
4766
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 _do_current_ffc_layer(scrollbuf, 0);
4767
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 draw_msgstr(0, scrollbuf);
4768
4769
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 set_draw_screen_clip(scrollbuf);
4770
4771 16127266 bool hero_draw_done = false;
4772
4/6
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16092514 times.
✓ Branch 3 taken 34752 times.
✓ Branch 4 taken 16092514 times.
✗ Branch 5 not taken.
16127266 bool is_cave_walking = ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom));
4773
2/2
✓ Branch 0 taken 343259 times.
✓ Branch 1 taken 15784007 times.
16127266 if(!(get_qr(qr_LAYER12UNDERCAVE)))
4774 {
4775
4/4
✓ Branch 0 taken 15782129 times.
✓ Branch 1 taken 1878 times.
✓ Branch 2 taken 88384 times.
✓ Branch 3 taken 15693745 times.
15784007 if(showhero && is_cave_walking)
4776 {
4777 88384 hero_draw_done = true;
4778
3/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 34752 times.
88384 if(Hero.getAction()==climbcovertop)
4779 {
4780 34752 cmby2=16;
4781 34752 }
4782
2/4
✓ Branch 0 taken 53632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53632 times.
53632 else if(Hero.getAction()==climbcoverbottom)
4783 {
4784 53632 cmby2=-16;
4785 53632 }
4786
4787
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw2(scrollbuf,true);
4788
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 Hero.draw(scrollbuf);
4789
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw(scrollbuf,true);
4790
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccx = (int32_t)Hero.getClimbCoverX();
4791
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccy = (int32_t)Hero.getClimbCoverY();
4792
4793
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4794
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4795
4796
4/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✓ Branch 5 taken 73152 times.
88384 if(int32_t(Hero.getX())&15)
4797 {
4798
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4799
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4800 15232 }
4801 88384 }
4802 15784007 }
4803
4804
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 16127266 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16127266 if (get_qr(qr_HERO_DIVE_UNDER_LAYER_1) && Hero.isDiving())
4805 {
4806 Hero.draw_under(scrollbuf);
4807 decorations.draw2(scrollbuf,true);
4808 Hero.draw(scrollbuf);
4809 decorations.draw(scrollbuf,true);
4810 hero_draw_done = true;
4811 }
4812
4813
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
32390850 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4814 16263584 do_layer(scrollbuf, 0, screen_handles[1], offx, offy); // LAYER 1
4815 16263584 });
4816
4817
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 do_layer_primitives(scrollbuf, 1);
4818
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 particles.draw(scrollbuf, true, 1);
4819
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 _do_current_ffc_layer(scrollbuf, 1);
4820
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 draw_msgstr(1, scrollbuf);
4821
4822 // Handle layer 2 NOT being used as background layers.
4823
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
32390850 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4824 16263584 mapscr* base_scr = screen_handles[0].base_scr;
4825
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 16121463 times.
16263584 if (!XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4826 16121463 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4827 16263584 });
4828
4829
2/2
✓ Branch 0 taken 15985145 times.
✓ Branch 1 taken 142121 times.
16127266 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4830 {
4831
1/2
✓ Branch 0 taken 15985145 times.
✗ Branch 1 not taken.
15985145 do_layer_primitives(scrollbuf, 2);
4832
1/2
✓ Branch 0 taken 15985145 times.
✗ Branch 1 not taken.
15985145 particles.draw(scrollbuf, true, 2);
4833 15985145 }
4834
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 _do_current_ffc_layer(scrollbuf, 2);
4835
2/2
✓ Branch 0 taken 15985145 times.
✓ Branch 1 taken 142121 times.
16127266 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4836
1/2
✓ Branch 0 taken 15985145 times.
✗ Branch 1 not taken.
15985145 draw_msgstr(2, scrollbuf);
4837
4838
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 do_primitives(scrollbuf, SPLAYER_FFC_DRAW);
4839
4840
2/2
✓ Branch 0 taken 15784007 times.
✓ Branch 1 taken 343259 times.
16127266 if(get_qr(qr_LAYER12UNDERCAVE))
4841 {
4842
2/4
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 343259 times.
343259 if(showhero && is_cave_walking)
4843 {
4844 hero_draw_done = true;
4845 if(Hero.getAction()==climbcovertop)
4846 {
4847 cmby2=16;
4848 }
4849 else if(Hero.getAction()==climbcoverbottom)
4850 {
4851 cmby2=-16;
4852 }
4853
4854 decorations.draw2(scrollbuf,true);
4855 Hero.draw(scrollbuf);
4856 decorations.draw(scrollbuf,true);
4857 int32_t ccx = (int32_t)(Hero.getClimbCoverX());
4858 int32_t ccy = (int32_t)(Hero.getClimbCoverY());
4859
4860 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4861 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4862
4863 if(int32_t(Hero.getX())&15)
4864 {
4865 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4866 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4867 }
4868 }
4869 343259 }
4870
4871
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15661217 times.
16127266 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4872 {
4873
1/2
✓ Branch 0 taken 15661217 times.
✗ Branch 1 not taken.
31458752 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4874 15797535 do_layer(scrollbuf, -2, screen_handles[0], offx, offy); // push blocks!
4875
2/2
✓ Branch 0 taken 14478915 times.
✓ Branch 1 taken 1318620 times.
15797535 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
4876 {
4877 1318620 do_layer(scrollbuf, -2, screen_handles[1], offx, offy); // push blocks!
4878 1318620 do_layer(scrollbuf, -2, screen_handles[2], offx, offy); // push blocks!
4879 1318620 }
4880 15797535 });
4881
4882
1/2
✓ Branch 0 taken 15661217 times.
✗ Branch 1 not taken.
15661217 do_primitives(scrollbuf, SPLAYER_PUSHBLOCK);
4883 15661217 }
4884
4885 // Show walkflags cheat
4886
2/4
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16127266 times.
16127266 if (show_walkflags || show_effectflags)
4887 {
4888 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4889 do_walkflags(screen_handles, offx, offy);
4890 do_effectflags(screen_handles[0].base_scr, offx, offy);
4891 });
4892
4893 do_walkflags(0, 0);
4894 }
4895
4896
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 putscrdoors(nearby_screens, scrollbuf, 0, playing_field_offset);
4897
4898 // Lens hints, doors etc.
4899
4/8
✓ Branch 0 taken 16117237 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 16117237 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 16117237 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
16127266 if(lensclk || (get_debug() && zc_getkey(KEY_L)))
4900 {
4901
2/2
✓ Branch 0 taken 4153 times.
✓ Branch 1 taken 5876 times.
10029 if(get_qr(qr_OLDLENSORDER))
4902 {
4903
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 draw_lens_under(scrollbuf, false);
4904
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4905 4153 }
4906
4907
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 draw_lens_under(scrollbuf, true);
4908
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_2);
4909 10029 }
4910
4911 // Blit those layers onto dest (framebuf)
4912
4913
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 set_draw_screen_clip(dest);
4914
4915
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 blit(scrollbuf, dest, 0, 0, 0, 0, 256, 232);
4916
4917 // After this point, scrollbuf is no longer drawn to - so things like dosubscr have access to a "partially rendered" frame.
4918 // I think only used for COOLSCROLL==0? Seems like a silly feature...
4919
4920 // Draw the subscreen, without clipping
4921
2/2
✓ Branch 0 taken 9251384 times.
✓ Branch 1 taken 6875882 times.
16127266 if(!get_qr(qr_SUBSCREENOVERSPRITES))
4922 {
4923 9251384 bool dotime = false;
4924
4/6
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3412853 times.
✓ Branch 3 taken 5838531 times.
✓ Branch 4 taken 3412853 times.
✗ Branch 5 not taken.
9251384 if (replay_version_check(22)) dotime = game->should_show_time();
4925
1/2
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
9251384 put_passive_subscr(dest, 0, 0, dotime, sspUP);
4926 9251384 }
4927
4928 // Draw some sprites onto dest
4929
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 set_clip_rect(dest,0,0,256,232);
4930
4931
2/2
✓ Branch 0 taken 99496 times.
✓ Branch 1 taken 16027770 times.
16127266 if(!(pricesdisplaybuf->clip))
4932 {
4933
1/2
✓ Branch 0 taken 99496 times.
✗ Branch 1 not taken.
99496 masked_blit(pricesdisplaybuf,dest,0,0,0,playing_field_offset,256,176);
4934 99496 }
4935
4936
5/6
✓ Branch 0 taken 16081640 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16075312 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16127266 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4937 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
4938
4939
4/4
✓ Branch 0 taken 16125388 times.
✓ Branch 1 taken 1878 times.
✓ Branch 2 taken 16037004 times.
✓ Branch 3 taken 88384 times.
16127266 if(showhero && !hero_draw_done)
4940 {
4941
1/2
✓ Branch 0 taken 16037004 times.
✗ Branch 1 not taken.
16037004 Hero.draw_under(dest);
4942
4943
3/4
✓ Branch 0 taken 16037004 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141385 times.
✓ Branch 3 taken 15895619 times.
16037004 if(Hero.isSwimming())
4944 {
4945
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw2(dest,true);
4946
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 Hero.draw(dest);
4947
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw(dest,true);
4948 141385 hero_draw_done = true;
4949 141385 }
4950 16037004 }
4951
4952 16127266 set<sprite*, SpriteSorter> sorted_sprites;
4953 16127266 vector<sprite*> temp_sprites;
4954 16127266 std::function<bool(sprite&)> add_sprite = [&](sprite& spr)
4955 {
4956 sorted_sprites.insert(&spr);
4957 return false;
4958 };
4959
4960
2/2
✓ Branch 0 taken 16124336 times.
✓ Branch 1 taken 2930 times.
16127266 if (classic_draw)
4961 {
4962
2/2
✓ Branch 0 taken 26095 times.
✓ Branch 1 taken 16098241 times.
16124336 if(drawguys)
4963 {
4964
4/4
✓ Branch 0 taken 1982674 times.
✓ Branch 1 taken 14115567 times.
✓ Branch 2 taken 991089 times.
✓ Branch 3 taken 991585 times.
16098241 if(get_qr(qr_NOFLICKER) || (frame&1))
4965 {
4966 // Just clips sprites if in a repeating, smooth maze.
4967
2/2
✓ Branch 0 taken 15097442 times.
✓ Branch 1 taken 9214 times.
15106656 bool do_clip = maze_state.active && maze_state.loopy;
4968
4969
1/2
✓ Branch 0 taken 15106656 times.
✗ Branch 1 not taken.
15106656 if(!get_qr(qr_OLD_WEAPON_DRAW_ANIMATE_TIMING))
4970 {
4971 if (do_clip)
4972 {
4973 Ewpns.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS));
4974 Lwpns.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS));
4975 }
4976 else
4977 {
4978 Ewpns.drawshadow(dest,get_qr(qr_TRANSSHADOWS),true);
4979 Lwpns.drawshadow(dest,get_qr(qr_TRANSSHADOWS),true);
4980 }
4981 }
4982
3/4
✓ Branch 0 taken 24911730 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9805074 times.
✓ Branch 3 taken 15106656 times.
24911730 for(int32_t i=0; i<Ewpns.Count(); i++)
4983 {
4984
3/4
✓ Branch 0 taken 9805074 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 250942 times.
✓ Branch 3 taken 9554132 times.
9805074 if(((weapon *)Ewpns.spr(i))->behind)
4985
2/4
✓ Branch 0 taken 250942 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 250942 times.
✗ Branch 3 not taken.
250942 Ewpns.spr(i)->draw(dest);
4986 9805074 }
4987
1/2
✓ Branch 0 taken 15106656 times.
✗ Branch 1 not taken.
15106656 do_primitives(dest, SPLAYER_EWEAP_BEHIND_DRAW);
4988
4989
3/4
✓ Branch 0 taken 21290647 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6183991 times.
✓ Branch 3 taken 15106656 times.
21290647 for(int32_t i=0; i<Lwpns.Count(); i++)
4990 {
4991
3/4
✓ Branch 0 taken 6183991 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1206996 times.
✓ Branch 3 taken 4976995 times.
6183991 if(((weapon *)Lwpns.spr(i))->behind)
4992
2/4
✓ Branch 0 taken 1206996 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1206996 times.
✗ Branch 3 not taken.
1206996 Lwpns.spr(i)->draw(dest);
4993 6183991 }
4994
1/2
✓ Branch 0 taken 15106656 times.
✗ Branch 1 not taken.
15106656 do_primitives(dest, SPLAYER_LWEAP_BEHIND_DRAW);
4995
4996
6/6
✓ Branch 0 taken 10369792 times.
✓ Branch 1 taken 4736864 times.
✓ Branch 2 taken 1348300 times.
✓ Branch 3 taken 9021492 times.
✓ Branch 4 taken 674011 times.
✓ Branch 5 taken 674289 times.
15106656 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4997 {
4998
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 9691845 times.
9695503 if (do_clip)
4999
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS)!=0);
5000 else
5001
1/2
✓ Branch 0 taken 9691845 times.
✗ Branch 1 not taken.
9691845 guys.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0,true);
5002 9695503 }
5003
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15102998 times.
15106656 if (do_clip)
5004
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.draw_smooth_maze(dest);
5005 else
5006
1/2
✓ Branch 0 taken 15102998 times.
✗ Branch 1 not taken.
15102998 guys.draw(dest,true);
5007
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15102998 times.
15106656 if (do_clip)
5008 {
5009 3658 int maze_screen = maze_state.scr->screen;
5010
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
5011
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
5012 3658 }
5013
1/2
✓ Branch 0 taken 15106656 times.
✗ Branch 1 not taken.
15106656 do_primitives(dest, SPLAYER_NPC_DRAW);
5014
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15102998 times.
15106656 if (do_clip)
5015
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(dest);
5016
5017
1/2
✓ Branch 0 taken 15106656 times.
✗ Branch 1 not taken.
15106656 chainlinks.draw(dest,true);
5018
1/2
✓ Branch 0 taken 15106656 times.
✗ Branch 1 not taken.
15106656 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5019 //Lwpns.draw(dest,true);
5020
5021
3/4
✓ Branch 0 taken 24911730 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9805074 times.
✓ Branch 3 taken 15106656 times.
24911730 for(int32_t i=0; i<Ewpns.Count(); i++)
5022 {
5023
3/4
✓ Branch 0 taken 9805074 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9554132 times.
✓ Branch 3 taken 250942 times.
9805074 if(!((weapon *)Ewpns.spr(i))->behind)
5024
2/4
✓ Branch 0 taken 9554132 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9554132 times.
✗ Branch 3 not taken.
9554132 Ewpns.spr(i)->draw(dest);
5025 9805074 }
5026
1/2
✓ Branch 0 taken 15106656 times.
✗ Branch 1 not taken.
15106656 do_primitives(dest, SPLAYER_EWEAP_FRONT_DRAW);
5027
5028
3/4
✓ Branch 0 taken 21290647 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6183991 times.
✓ Branch 3 taken 15106656 times.
21290647 for(int32_t i=0; i<Lwpns.Count(); i++)
5029 {
5030
3/4
✓ Branch 0 taken 6183991 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4976995 times.
✓ Branch 3 taken 1206996 times.
6183991 if(!((weapon *)Lwpns.spr(i))->behind)
5031
2/4
✓ Branch 0 taken 4976995 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4976995 times.
✗ Branch 3 not taken.
4976995 Lwpns.spr(i)->draw(dest);
5032 6183991 }
5033
1/2
✓ Branch 0 taken 15106656 times.
✗ Branch 1 not taken.
15106656 do_primitives(dest, SPLAYER_LWEAP_FRONT_DRAW);
5034
5035
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15102998 times.
15106656 if (do_clip)
5036
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 items.draw_smooth_maze(dest);
5037 else
5038
1/2
✓ Branch 0 taken 15102998 times.
✗ Branch 1 not taken.
15102998 items.draw(dest,true);
5039
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15102998 times.
15106656 if (do_clip)
5040 {
5041 3658 int maze_screen = maze_state.scr->screen;
5042
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
5043
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
5044 3658 }
5045
1/2
✓ Branch 0 taken 15106656 times.
✗ Branch 1 not taken.
15106656 do_primitives(dest, SPLAYER_ITEMSPRITE_DRAW);
5046
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15102998 times.
15106656 if (do_clip)
5047
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(dest);
5048 15106656 }
5049 else
5050 {
5051
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
5052 {
5053
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✓ Branch 3 taken 496727 times.
505372 if(((weapon *)Ewpns.spr(i))->behind)
5054
2/4
✓ Branch 0 taken 8645 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
8645 Ewpns.spr(i)->draw(dest);
5055 505372 }
5056
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_EWEAP_BEHIND_DRAW);
5057
5058
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
5059 {
5060
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 231146 times.
231146 if(((weapon *)Lwpns.spr(i))->behind)
5061 Lwpns.spr(i)->draw(dest);
5062 231146 }
5063
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_LWEAP_BEHIND_DRAW);
5064
5065
3/4
✓ Branch 0 taken 228620 times.
✓ Branch 1 taken 762965 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228620 times.
991585 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5066 {
5067
1/2
✓ Branch 0 taken 228620 times.
✗ Branch 1 not taken.
228620 guys.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0,true);
5068 228620 }
5069
5070
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 items.draw(dest,false);
5071
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_ITEMSPRITE_DRAW);
5072
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 chainlinks.draw(dest,false);
5073
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5074 //Lwpns.draw(dest,false);
5075
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 guys.draw(dest,false);
5076
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_NPC_DRAW);
5077
5078
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
5079 {
5080
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✓ Branch 3 taken 8645 times.
505372 if(!((weapon *)Ewpns.spr(i))->behind)
5081 {
5082
2/4
✓ Branch 0 taken 496727 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✗ Branch 3 not taken.
496727 Ewpns.spr(i)->draw(dest);
5083 496727 }
5084 505372 }
5085
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_EWEAP_FRONT_DRAW);
5086
5087
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
5088 {
5089
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 if(!((weapon *)Lwpns.spr(i))->behind)
5090 {
5091
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 Lwpns.spr(i)->draw(dest);
5092 231146 }
5093 231146 }
5094
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_LWEAP_FRONT_DRAW);
5095 }
5096
5097
1/2
✓ Branch 0 taken 16098241 times.
✗ Branch 1 not taken.
16098241 guys.draw2(dest,true);
5098 16098241 }
5099
5100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16124336 times.
16124336 if(mirror_portal.destdmap > -1)
5101 mirror_portal.draw(dest);
5102
1/2
✓ Branch 0 taken 16124336 times.
✗ Branch 1 not taken.
16124336 portals.draw(dest,true);
5103
5104
4/4
✓ Branch 0 taken 16122458 times.
✓ Branch 1 taken 1878 times.
✓ Branch 2 taken 88384 times.
✓ Branch 3 taken 16034074 times.
16124336 if(showhero && !is_cave_walking)
5105 {
5106
2/2
✓ Branch 0 taken 15574441 times.
✓ Branch 1 taken 459633 times.
16034074 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
5107 {
5108
1/2
✓ Branch 0 taken 15574441 times.
✗ Branch 1 not taken.
15574441 mblock2.draw(dest,-1);
5109
1/2
✓ Branch 0 taken 15574441 times.
✗ Branch 1 not taken.
15574441 do_primitives(dest, SPLAYER_MOVINGBLOCK);
5110 15574441 }
5111
2/2
✓ Branch 0 taken 15892689 times.
✓ Branch 1 taken 141385 times.
16034074 if(!hero_draw_done)
5112 {
5113
8/12
✓ Branch 0 taken 15892689 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15892689 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15873519 times.
✓ Branch 5 taken 19170 times.
✓ Branch 6 taken 15873519 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15873519 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1370 times.
✓ Branch 11 taken 15891319 times.
15892689 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5114 {
5115
2/2
✓ Branch 0 taken 18485 times.
✓ Branch 1 taken 15874204 times.
15892689 Hero.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0);
5116 18485 }
5117
5118
6/8
✓ Branch 0 taken 15892689 times.
✓ Branch 1 taken 15874204 times.
✓ Branch 2 taken 15892689 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15892689 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15878625 times.
✓ Branch 7 taken 14064 times.
18485 if(Hero.getZ() <= (zfix)zinit.jump_hero_layer_threshold)
5119 {
5120
1/2
✓ Branch 0 taken 15878625 times.
✗ Branch 1 not taken.
15878625 decorations.draw2(dest,true);
5121
1/2
✓ Branch 0 taken 15878625 times.
✗ Branch 1 not taken.
15878625 Hero.draw(dest);
5122
1/2
✓ Branch 0 taken 15878625 times.
✗ Branch 1 not taken.
15878625 decorations.draw(dest,true);
5123 15878625 hero_draw_done = true;
5124 15878625 }
5125 15892689 }
5126 16034074 }
5127
5128
3/4
✓ Branch 0 taken 56541904 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40417568 times.
✓ Branch 3 taken 16124336 times.
56541904 for(int32_t i=0; i<guys.Count(); i++)
5129 {
5130
3/4
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16520322 times.
✓ Branch 3 taken 23897246 times.
40417568 if(((enemy*)guys.spr(i))->type == eeWALK)
5131 {
5132
3/4
✓ Branch 0 taken 16520322 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7965 times.
✓ Branch 3 taken 16512357 times.
16520322 if(((eStalfos*)guys.spr(i))->hashero)
5133 {
5134
2/4
✓ Branch 0 taken 7965 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7965 times.
✗ Branch 3 not taken.
7965 guys.spr(i)->draw(dest);
5135 7965 }
5136 16520322 }
5137
5138
3/4
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 507162 times.
✓ Branch 3 taken 39910406 times.
40417568 if(((enemy*)guys.spr(i))->type == eeWALLM)
5139 {
5140
3/4
✓ Branch 0 taken 507162 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✓ Branch 3 taken 505833 times.
507162 if(((eWallM*)guys.spr(i))->hashero)
5141 {
5142
2/4
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
1329 guys.spr(i)->draw(dest);
5143 1329 }
5144 507162 }
5145
5146
11/20
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40417568 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40417568 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 40417568 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 40417568 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 40417568 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 40417568 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 40417568 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 40417568 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1523506 times.
✓ Branch 19 taken 38894062 times.
40417568 if(guys.spr(i)->z+guys.spr(i)->fakez > Hero.getZ()+Hero.getFakeZ())
5147 {
5148 //Jumping enemies in front of Hero.
5149
2/4
✓ Branch 0 taken 1523506 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1523506 times.
✗ Branch 3 not taken.
1523506 guys.spr(i)->draw(dest);
5150 1523506 }
5151
1/2
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
40417568 do_primitives(dest, SPLAYER_NPC_ABOVEPLAYER_DRAW);
5152 40417568 }
5153 16124336 }
5154 else
5155 {
5156
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if(drawguys)
5157 {
5158
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 chainlinks.forEach(add_sprite);
5159
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
5860 bool show_enemy_shadows = (get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1));
5160 25837 auto add_spr_shadow = [&](sprite& spr)
5161 {
5162 22907 sorted_sprites.insert(&spr);
5163
3/4
✓ Branch 0 taken 1291 times.
✓ Branch 1 taken 21616 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1291 times.
22907 if(spr.total_z() > 0 && spr.can_drawshadow())
5164 {
5165
1/2
✓ Branch 0 taken 1291 times.
✗ Branch 1 not taken.
1291 tempsprite_shadow* shadow = new tempsprite_shadow(&spr);
5166 1291 sorted_sprites.insert(shadow);
5167 1291 temp_sprites.push_back(shadow);
5168 1291 }
5169 22907 return false;
5170 };
5171
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 Lwpns.forEach(add_spr_shadow);
5172
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 Ewpns.forEach(add_spr_shadow);
5173
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 items.forEach(add_spr_shadow);
5174
4/14
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2930 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2930 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2930 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2930 guys.forEach(show_enemy_shadows ? add_spr_shadow : add_sprite);
5175 2930 }
5176
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 if(showhero && !hero_draw_done)
5177 {
5178
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 sorted_sprites.insert(&Hero);
5179
9/14
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2290 times.
✓ Branch 5 taken 640 times.
✓ Branch 6 taken 2290 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2290 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2930 times.
✓ Branch 12 taken 2290 times.
✓ Branch 13 taken 2290 times.
2930 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5180 {
5181
3/4
✓ Branch 0 taken 640 times.
✓ Branch 1 taken 4580 times.
✓ Branch 2 taken 640 times.
✗ Branch 3 not taken.
5220 tempsprite_shadow* shadow = new tempsprite_shadow(&Hero);
5182
1/2
✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
640 sorted_sprites.insert(shadow);
5183
1/2
✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
640 temp_sprites.push_back(shadow);
5184 640 }
5185 2930 }
5186
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if(mirror_portal.destdmap > -1)
5187 sorted_sprites.insert(&mirror_portal);
5188
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 portals.forEach(add_sprite);
5189
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
5190
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 sorted_sprites.insert(&mblock2);
5191 }
5192 16127266 auto sprite_it = sorted_sprites.begin();
5193
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16124336 times.
16127266 if (!classic_draw)
5194
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_GROUND]);
5195
5196 // Draw some layers onto dest
5197
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 set_draw_screen_clip(dest);
5198
5/6
✓ Branch 0 taken 16081640 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16075312 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16127266 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5199 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5200
5201 // Handle layer 3 NOT being used as background layers.
5202
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
32390850 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5203 16263584 mapscr* base_scr = screen_handles[0].base_scr;
5204
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 16029020 times.
16263584 if (!XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5205 16029020 do_layer(dest, 0, screen_handles[3], offx, offy);
5206 16263584 });
5207
5208
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16124336 times.
16127266 if (!classic_draw)
5209
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_3]);
5210
5211
2/2
✓ Branch 0 taken 15892702 times.
✓ Branch 1 taken 234564 times.
16127266 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5212 {
5213
1/2
✓ Branch 0 taken 15892702 times.
✗ Branch 1 not taken.
15892702 do_layer_primitives(dest, 3);
5214
1/2
✓ Branch 0 taken 15892702 times.
✗ Branch 1 not taken.
15892702 particles.draw(dest, true, 3);
5215 15892702 }
5216
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 _do_current_ffc_layer(dest, 3);
5217
2/2
✓ Branch 0 taken 15892702 times.
✓ Branch 1 taken 234564 times.
16127266 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5218
1/2
✓ Branch 0 taken 15892702 times.
✗ Branch 1 not taken.
15892702 draw_msgstr(3);
5219
5220
5221
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
32390850 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5222 16263584 do_layer(dest, 0, screen_handles[4], offx, offy);
5223 16263584 });
5224
5225
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16124336 times.
16127266 if (!classic_draw)
5226
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_4]);
5227
5228
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 do_layer_primitives(dest, 4);
5229
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 particles.draw(dest, true, 4);
5230
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 _do_current_ffc_layer(dest, 4);
5231
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 draw_msgstr(4);
5232
5233
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
32390850 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5234 16263584 do_layer(dest, -1, screen_handles[0], offx, offy);
5235
2/2
✓ Branch 0 taken 14402748 times.
✓ Branch 1 taken 1860836 times.
16263584 if (get_qr(qr_OVERHEAD_COMBOS_L1_L2))
5236 {
5237 1860836 do_layer(dest, -1, screen_handles[1], offx, offy);
5238 1860836 do_layer(dest, -1, screen_handles[2], offx, offy);
5239 1860836 }
5240 16263584 });
5241
5242
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 do_primitives(dest, SPLAYER_OVERHEAD_CMB);
5243
5244 // Draw some flying sprites onto dest
5245
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 clear_clip_rect(dest);
5246
5/6
✓ Branch 0 taken 16081640 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16075312 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16127266 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5247 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5248
5249
2/2
✓ Branch 0 taken 16124336 times.
✓ Branch 1 taken 2930 times.
16127266 if (classic_draw)
5250 {
5251 //Jumping Hero and jumping enemies are drawn on this layer.
5252
5/8
✓ Branch 0 taken 16124336 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16124336 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16124336 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14064 times.
✓ Branch 7 taken 16110272 times.
16124336 if(Hero.getZ() > (zfix)zinit.jump_hero_layer_threshold)
5253 {
5254
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw2(dest,false);
5255
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 Hero.draw(dest);
5256
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 chainlinks.draw(dest,true);
5257
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5258
5259
3/4
✓ Branch 0 taken 16806 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✓ Branch 3 taken 14064 times.
16806 for(int32_t i=0; i<Lwpns.Count(); i++)
5260 {
5261
9/16
✓ Branch 0 taken 2742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2742 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2742 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2742 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2742 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 239 times.
✓ Branch 15 taken 2503 times.
2742 if(Lwpns.spr(i)->z+Lwpns.spr(i)->fakez > (zfix)zinit.jump_hero_layer_threshold)
5262 {
5263
2/4
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 Lwpns.spr(i)->draw(dest);
5264 239 }
5265 2742 }
5266
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(dest, SPLAYER_LWEAP_ABOVE_DRAW);
5267
5268
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw(dest,false);
5269 14064 }
5270
5271
5/6
✓ Branch 0 taken 3872571 times.
✓ Branch 1 taken 12251765 times.
✓ Branch 2 taken 44335356 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32083591 times.
✓ Branch 5 taken 12251765 times.
48207927 if(!get_qr(qr_ENEMIESZAXIS)) for(int32_t i=0; i<guys.Count(); i++)
5272 {
5273
13/22
✓ Branch 0 taken 32083591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32083591 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27177493 times.
✓ Branch 5 taken 4906098 times.
✓ Branch 6 taken 27177493 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27177493 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27177493 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27177493 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27177493 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27177493 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27177493 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6568 times.
✓ Branch 21 taken 27170925 times.
32083591 if((isflier(guys.spr(i)->id)) || (guys.spr(i)->z+guys.spr(i)->fakez) > (zfix)zinit.jump_hero_layer_threshold)
5274 {
5275
2/4
✓ Branch 0 taken 4912666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4912666 times.
✗ Branch 3 not taken.
4912666 guys.spr(i)->draw(dest);
5276 4912666 }
5277 44335356 }
5278 else
5279 {
5280
3/4
✓ Branch 0 taken 12206548 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8333977 times.
✓ Branch 3 taken 3872571 times.
12206548 for(int32_t i=0; i<guys.Count(); i++)
5281 {
5282
13/22
✓ Branch 0 taken 8333977 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8333977 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6997572 times.
✓ Branch 5 taken 1336405 times.
✓ Branch 6 taken 6997572 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6997572 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6997572 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6478745 times.
✓ Branch 13 taken 518827 times.
✓ Branch 14 taken 6478745 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 6478745 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 6478745 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 6478745 times.
8333977 if((isflier(guys.spr(i)->id)) || guys.spr(i)->z > 0 || guys.spr(i)->fakez > 0)
5283 {
5284
2/4
✓ Branch 0 taken 1855232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1855232 times.
✗ Branch 3 not taken.
1855232 guys.spr(i)->draw(dest);
5285 1855232 }
5286 8333977 }
5287 }
5288
1/2
✓ Branch 0 taken 16124336 times.
✗ Branch 1 not taken.
16124336 do_primitives(dest, SPLAYER_NPC_AIRBORNE_DRAW);
5289 16124336 }
5290
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 else draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_OVERHEAD]);
5291
5292 // Draw the Moving Fairy above layer 3
5293
3/4
✓ Branch 0 taken 19450532 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3323266 times.
✓ Branch 3 taken 16127266 times.
19450532 for(int32_t i=0; i<items.Count(); i++)
5294
6/8
✓ Branch 0 taken 3323266 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 70250 times.
✓ Branch 3 taken 3253016 times.
✓ Branch 4 taken 70250 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60536 times.
✓ Branch 7 taken 9714 times.
3383802 if(itemsbuf[items.spr(i)->id].type == itype_fairy && itemsbuf[items.spr(i)->id].misc3)
5295
2/4
✓ Branch 0 taken 60536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60536 times.
✗ Branch 3 not taken.
60536 items.spr(i)->draw(dest);
5296
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 do_primitives(dest, SPLAYER_FAIRYITEM_DRAW);
5297
5298 // Draw some layers onto dest
5299
5300
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 set_draw_screen_clip(dest);
5301
5302
2/2
✓ Branch 0 taken 16112914 times.
✓ Branch 1 taken 14352 times.
16127266 if (lightbeam_present)
5303 {
5304 14352 color_map = &trans_table2;
5305
2/2
✓ Branch 0 taken 13114 times.
✓ Branch 1 taken 1238 times.
14352 if(get_qr(qr_LIGHTBEAM_TRANSPARENT))
5306
1/2
✓ Branch 0 taken 13114 times.
✗ Branch 1 not taken.
13114 draw_trans_sprite(dest, lightbeam_bmp, 0, playing_field_offset);
5307 else
5308
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 masked_blit(lightbeam_bmp, dest, 0, 0, 0, playing_field_offset, 256, 176);
5309 14352 color_map = &trans_table;
5310 14352 }
5311
5312
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
32390850 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5313 16263584 do_layer(dest, 0, screen_handles[5], offx, offy);
5314 16263584 });
5315
5316
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16124336 times.
16127266 if (!classic_draw)
5317
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_5]);
5318
5319
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 do_layer_primitives(dest, 5);
5320
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 particles.draw(dest, true, 5);
5321
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 _do_current_ffc_layer(dest, 5);
5322
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 draw_msgstr(5);
5323
5324
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 _do_current_ffc_layer(dest, -1000); // 'overhead' freeform combos
5325
5326
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 do_primitives(dest, SPLAYER_OVERHEAD_FFC);
5327
5328
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
32390850 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5329 16263584 do_layer(dest, 0, screen_handles[6], offx, offy);
5330 16263584 });
5331
5332
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16124336 times.
16127266 if (!classic_draw)
5333
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, word(-1));
5334
5335
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 do_layer_primitives(dest, 6);
5336
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 particles.draw(dest, true, 6);
5337
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 _do_current_ffc_layer(dest, 6);
5338
5339 16127266 bool any_dark = false;
5340
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
32390850 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5341 16263584 mapscr* base_scr = screen_handles[0].scr;
5342 16263584 any_dark |= is_dark(base_scr);
5343 16263584 });
5344
5345 // Handle low drawn darkness
5346
4/4
✓ Branch 0 taken 1857053 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 1510154 times.
✓ Branch 3 taken 346899 times.
16127266 if(get_qr(qr_NEW_DARKROOM) && any_dark)
5347 {
5348
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
700032 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5349 353133 mapscr* base_scr = screen_handles[0].scr;
5350 353133 calc_darkroom_combos(base_scr, offx, offy + playing_field_offset);
5351 353133 calc_darkroom_ffcs(base_scr, 0, playing_field_offset);
5352 353133 });
5353
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
346899 if(showhero)
5354
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
346899 Hero.calc_darkroom_hero(0, -playing_field_offset);
5355
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
700032 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5356 353133 mapscr* base_scr = screen_handles[0].scr;
5357
2/2
✓ Branch 0 taken 348403 times.
✓ Branch 1 taken 4730 times.
353133 if (!is_dark(base_scr))
5358 {
5359 4730 offy += playing_field_offset;
5360 4730 rectfill(darkscr_bmp, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5361 4730 rectfill(darkscr_bmp_trans, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5362 4730 }
5363 353133 });
5364 346899 }
5365
5366 //Darkroom if under the subscreen
5367
6/6
✓ Branch 0 taken 1857053 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 1409427 times.
✓ Branch 3 taken 447626 times.
✓ Branch 4 taken 334908 times.
✓ Branch 5 taken 1074519 times.
16127266 if(get_qr(qr_NEW_DARKROOM) && get_qr(qr_NEWDARK_L6) && any_dark)
5368 {
5369
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 do_primitives(dest, SPLAYER_DARKROOM_UNDER);
5370
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 set_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5371
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 334908 times.
334908 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5372 {
5373 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5374 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5375 }
5376
5377 334908 color_map = &trans_table2;
5378
2/2
✓ Branch 0 taken 15523 times.
✓ Branch 1 taken 319385 times.
334908 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5379 {
5380
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 draw_trans_sprite(dest, darkscr_bmp, 0, 0);
5381
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5382
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
5383 15523 }
5384 else
5385 {
5386
1/2
✓ Branch 0 taken 319385 times.
✗ Branch 1 not taken.
319385 masked_blit(darkscr_bmp, dest, 0, 0, 0, 0, dest->w, dest->h);
5387
1/2
✓ Branch 0 taken 319385 times.
✗ Branch 1 not taken.
319385 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
5388 }
5389 334908 color_map = &trans_table;
5390
5391
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 set_clip_rect(dest, 0, 0, dest->w, dest->h);
5392
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 do_primitives(dest, SPLAYER_DARKROOM_OVER);
5393 334908 }
5394
5395
3/6
✓ Branch 0 taken 51954 times.
✓ Branch 1 taken 16075312 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 51954 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16127266 if (is_in_scrolling_region() && lensclk && !FFCore.system_suspend[susptLENS])
5396 {
5397 draw_lens_over(dest);
5398 --lensclk;
5399 }
5400
5401 // Draw some text on dest
5402
5403
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 set_clip_rect(dest,0,0,256,232);
5404
5405
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 if(!get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5406
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 draw_msgstr(6);
5407
5408 // Draw the subscreen, without clipping
5409
2/2
✓ Branch 0 taken 6875882 times.
✓ Branch 1 taken 9251384 times.
16127266 if(get_qr(qr_SUBSCREENOVERSPRITES))
5410 {
5411
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 6833626 times.
6875882 if (drawPassiveSubscreenSeparate)
5412
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 blit(dest, framebuf_no_passive_subscreen, 0, 0, 0, 0, dest->w, dest->h);
5413
5414
2/4
✓ Branch 0 taken 6875882 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6875882 times.
✗ Branch 3 not taken.
6875882 put_passive_subscr(dest, 0, 0, game->should_show_time(), sspUP);
5415
5416
1/2
✓ Branch 0 taken 6875882 times.
✗ Branch 1 not taken.
6875882 do_primitives(dest, 7);
5417
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 6833626 times.
6875882 if (drawPassiveSubscreenSeparate)
5418
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 do_primitives(framebuf_no_passive_subscreen, 7);
5419 6875882 }
5420
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9251384 times.
9251384 else if (!classic_draw)
5421 do_primitives(dest, 7);
5422
5423
1/2
✓ Branch 0 taken 16127266 times.
✗ Branch 1 not taken.
16127266 draw_screen_post_passive_subscreen(dest, any_dark);
5424
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 16085010 times.
16127266 if (drawPassiveSubscreenSeparate)
5425
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 draw_screen_post_passive_subscreen(framebuf_no_passive_subscreen, any_dark);
5426
5427
2/2
✓ Branch 0 taken 15625722 times.
✓ Branch 1 taken 31752988 times.
16127266 set_clip_rect(scrollbuf, 0, 0, scrollbuf->w, scrollbuf->h);
5428
3/4
✓ Branch 0 taken 15513893 times.
✓ Branch 1 taken 158807 times.
✓ Branch 2 taken 15513893 times.
✗ Branch 3 not taken.
15625722 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_POST_DRAW);
5429
5430
2/2
✓ Branch 0 taken 1931 times.
✓ Branch 1 taken 15672700 times.
15674631 for(sprite* spr : temp_sprites)
5431
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1931 times.
1931 delete spr;
5432 79178676 }
5433
5434 // TODO: separate setting door data and drawing door
5435 28153 void put_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t type, bool redraw, bool even_walls)
5436 {
5437
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28153 times.
28153 if (type > 8) return;
5438
5439 28153 int32_t d=scr->door_combo_set;
5440
5441
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15611 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12542 times.
28153 switch(type)
5442 {
5443 case dt_wall:
5444 case dt_walk:
5445 if(!even_walls)
5446 break;
5447 [[fallthrough]];
5448 case dt_pass:
5449
3/4
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 11506 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1036 times.
12542 if(!get_qr(qr_REPLACEOPENDOORS) && !even_walls)
5450 1036 break;
5451 [[fallthrough]];
5452 case dt_lock:
5453 case dt_shut:
5454 case dt_boss:
5455 case dt_olck:
5456 case dt_osht:
5457 case dt_obos:
5458 case dt_bomb:
5459
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7259 times.
✓ Branch 2 taken 6784 times.
✓ Branch 3 taken 6362 times.
✓ Branch 4 taken 6712 times.
27117 switch(side)
5460 {
5461 case up:
5462 7259 scr->data[pos] = DoorComboSets[d].doorcombo_u[type][0];
5463 7259 scr->cset[pos] = DoorComboSets[d].doorcset_u[type][0];
5464 7259 scr->sflag[pos] = 0;
5465 7259 scr->data[pos+1] = DoorComboSets[d].doorcombo_u[type][1];
5466 7259 scr->cset[pos+1] = DoorComboSets[d].doorcset_u[type][1];
5467 7259 scr->sflag[pos+1] = 0;
5468 7259 scr->data[pos+16] = DoorComboSets[d].doorcombo_u[type][2];
5469 7259 scr->cset[pos+16] = DoorComboSets[d].doorcset_u[type][2];
5470 7259 scr->sflag[pos+16] = 0;
5471 7259 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_u[type][3];
5472 7259 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_u[type][3];
5473 7259 scr->sflag[pos+16+1] = 0;
5474
5475
2/2
✓ Branch 0 taken 5435 times.
✓ Branch 1 taken 1824 times.
7259 if(redraw)
5476 {
5477 3648 putcombo(dest,(pos&15)<<4,pos&0xF0,
5478 1824 DoorComboSets[d].doorcombo_u[type][0],
5479 1824 DoorComboSets[d].doorcset_u[type][0]);
5480 3648 putcombo(dest,((pos&15)<<4)+16,pos&0xF0,
5481 1824 DoorComboSets[d].doorcombo_u[type][1],
5482 1824 DoorComboSets[d].doorcset_u[type][1]);
5483 1824 }
5484
5485 7259 break;
5486
5487 case down:
5488 6784 scr->data[pos] = DoorComboSets[d].doorcombo_d[type][0];
5489 6784 scr->cset[pos] = DoorComboSets[d].doorcset_d[type][0];
5490 6784 scr->sflag[pos] = 0;
5491 6784 scr->data[pos+1] = DoorComboSets[d].doorcombo_d[type][1];
5492 6784 scr->cset[pos+1] = DoorComboSets[d].doorcset_d[type][1];
5493 6784 scr->sflag[pos+1] = 0;
5494 6784 scr->data[pos+16] = DoorComboSets[d].doorcombo_d[type][2];
5495 6784 scr->cset[pos+16] = DoorComboSets[d].doorcset_d[type][2];
5496 6784 scr->sflag[pos+16] = 0;
5497 6784 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_d[type][3];
5498 6784 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_d[type][3];
5499 6784 scr->sflag[pos+16+1] = 0;
5500
5501
2/2
✓ Branch 0 taken 5463 times.
✓ Branch 1 taken 1321 times.
6784 if(redraw)
5502 {
5503 2642 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5504 1321 DoorComboSets[d].doorcombo_d[type][2],
5505 1321 DoorComboSets[d].doorcset_d[type][2]);
5506 2642 putcombo(dest,((pos&15)<<4)+16,(pos&0xF0)+16,
5507 1321 DoorComboSets[d].doorcombo_d[type][3],
5508 1321 DoorComboSets[d].doorcset_d[type][3]);
5509 1321 }
5510
5511 6784 break;
5512
5513 case left:
5514 6362 scr->data[pos] = DoorComboSets[d].doorcombo_l[type][0];
5515 6362 scr->cset[pos] = DoorComboSets[d].doorcset_l[type][0];
5516 6362 scr->sflag[pos] = 0;
5517 6362 scr->data[pos+1] = DoorComboSets[d].doorcombo_l[type][1];
5518 6362 scr->cset[pos+1] = DoorComboSets[d].doorcset_l[type][1];
5519 6362 scr->sflag[pos+1] = 0;
5520 6362 scr->data[pos+16] = DoorComboSets[d].doorcombo_l[type][2];
5521 6362 scr->cset[pos+16] = DoorComboSets[d].doorcset_l[type][2];
5522 6362 scr->sflag[pos+16] = 0;
5523 6362 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_l[type][3];
5524 6362 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_l[type][3];
5525 6362 scr->sflag[pos+16+1] = 0;
5526 6362 scr->data[pos+32] = DoorComboSets[d].doorcombo_l[type][4];
5527 6362 scr->cset[pos+32] = DoorComboSets[d].doorcset_l[type][4];
5528 6362 scr->sflag[pos+32] = 0;
5529 6362 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_l[type][5];
5530 6362 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_l[type][5];
5531 6362 scr->sflag[pos+32+1] = 0;
5532
5533
2/2
✓ Branch 0 taken 4873 times.
✓ Branch 1 taken 1489 times.
6362 if(redraw)
5534 {
5535 2978 putcombo(dest,(pos&15)<<4,pos&0xF0,
5536 1489 DoorComboSets[d].doorcombo_l[type][0],
5537 1489 DoorComboSets[d].doorcset_l[type][0]);
5538 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5539 1489 DoorComboSets[d].doorcombo_l[type][2],
5540 1489 DoorComboSets[d].doorcset_l[type][2]);
5541 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5542 1489 DoorComboSets[d].doorcombo_l[type][4],
5543 1489 DoorComboSets[d].doorcset_l[type][4]);
5544 1489 }
5545
5546 6362 break;
5547
5548 case right:
5549 6712 scr->data[pos] = DoorComboSets[d].doorcombo_r[type][0];
5550 6712 scr->cset[pos] = DoorComboSets[d].doorcset_r[type][0];
5551 6712 scr->sflag[pos] = 0;
5552 6712 scr->data[pos+1] = DoorComboSets[d].doorcombo_r[type][1];
5553 6712 scr->cset[pos+1] = DoorComboSets[d].doorcset_r[type][1];
5554 6712 scr->sflag[pos+1] = 0;
5555 6712 scr->data[pos+16] = DoorComboSets[d].doorcombo_r[type][2];
5556 6712 scr->cset[pos+16] = DoorComboSets[d].doorcset_r[type][2];
5557 6712 scr->sflag[pos+16] = 0;
5558 6712 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_r[type][3];
5559 6712 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_r[type][3];
5560 6712 scr->sflag[pos+16+1] = 0;
5561 6712 scr->data[pos+32] = DoorComboSets[d].doorcombo_r[type][4];
5562 6712 scr->cset[pos+32] = DoorComboSets[d].doorcset_r[type][4];
5563 6712 scr->sflag[pos+32] = 0;
5564 6712 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_r[type][5];
5565 6712 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_r[type][5];
5566 6712 scr->sflag[pos+32+1] = 0;
5567
5568
2/2
✓ Branch 0 taken 5058 times.
✓ Branch 1 taken 1654 times.
6712 if(redraw)
5569 {
5570 3308 putcombo(dest,(pos&15)<<4,pos&0xF0,
5571 1654 DoorComboSets[d].doorcombo_r[type][0],
5572 1654 DoorComboSets[d].doorcset_r[type][0]);
5573 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5574 1654 DoorComboSets[d].doorcombo_r[type][2],
5575 1654 DoorComboSets[d].doorcset_r[type][2]);
5576 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5577 1654 DoorComboSets[d].doorcombo_r[type][4],
5578 1654 DoorComboSets[d].doorcset_r[type][4]);
5579 1654 }
5580
5581 6712 break;
5582 }
5583
5584 27117 break;
5585
5586 default:
5587 break;
5588 }
5589 28153 }
5590
5591 706556 static void over_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t offx, int32_t offy)
5592 {
5593 706556 int32_t door_combo_set = scr->door_combo_set;
5594 706556 int32_t x = (pos&15)<<4;
5595 706556 int32_t y = (pos&0xF0);
5596 706556 int32_t d = door_combo_set;
5597 706556 x += offx;
5598 706556 y += offy;
5599
5600
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 161136 times.
✓ Branch 2 taken 179643 times.
✓ Branch 3 taken 196353 times.
✓ Branch 4 taken 169424 times.
706556 switch(side)
5601 {
5602 case up:
5603 322272 overcombo2(dest,x,y,
5604 161136 DoorComboSets[d].bombdoorcombo_u[0],
5605 161136 DoorComboSets[d].bombdoorcset_u[0]);
5606 322272 overcombo2(dest,x+16,y,
5607 161136 DoorComboSets[d].bombdoorcombo_u[1],
5608 161136 DoorComboSets[d].bombdoorcset_u[1]);
5609 161136 break;
5610
5611 case down:
5612 359286 overcombo2(dest,x,y,
5613 179643 DoorComboSets[d].bombdoorcombo_d[0],
5614 179643 DoorComboSets[d].bombdoorcset_d[0]);
5615 359286 overcombo2(dest,x+16,y,
5616 179643 DoorComboSets[d].bombdoorcombo_d[1],
5617 179643 DoorComboSets[d].bombdoorcset_d[1]);
5618 179643 break;
5619
5620 case left:
5621 392706 overcombo2(dest,x,y,
5622 196353 DoorComboSets[d].bombdoorcombo_l[0],
5623 196353 DoorComboSets[d].bombdoorcset_l[0]);
5624 392706 overcombo2(dest,x,y+16,
5625 196353 DoorComboSets[d].bombdoorcombo_l[1],
5626 196353 DoorComboSets[d].bombdoorcset_l[1]);
5627 392706 overcombo2(dest,x,y+16,
5628 196353 DoorComboSets[d].bombdoorcombo_l[2],
5629 196353 DoorComboSets[d].bombdoorcset_l[2]);
5630 196353 break;
5631
5632 case right:
5633 338848 overcombo2(dest,x,y,
5634 169424 DoorComboSets[d].bombdoorcombo_r[0],
5635 169424 DoorComboSets[d].bombdoorcset_r[0]);
5636 338848 overcombo2(dest,x,y+16,
5637 169424 DoorComboSets[d].bombdoorcombo_r[1],
5638 169424 DoorComboSets[d].bombdoorcset_r[1]);
5639 338848 overcombo2(dest,x,y+16,
5640 169424 DoorComboSets[d].bombdoorcombo_r[2],
5641 169424 DoorComboSets[d].bombdoorcset_r[2]);
5642 169424 break;
5643 }
5644 706556 }
5645
5646 47568 void update_door(mapscr* scr, int32_t side, int32_t door, bool even_walls)
5647 {
5648
7/8
✓ Branch 0 taken 47460 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 47460 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22925 times.
✓ Branch 5 taken 24535 times.
✓ Branch 6 taken 530 times.
✓ Branch 7 taken 22395 times.
47568 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5649 25173 return;
5650
5651 int32_t doortype;
5652
5653
10/12
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 655 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12492 times.
✓ Branch 5 taken 910 times.
✓ Branch 6 taken 1553 times.
✓ Branch 7 taken 3192 times.
✓ Branch 8 taken 1694 times.
✓ Branch 9 taken 172 times.
✓ Branch 10 taken 67 times.
✓ Branch 11 taken 1138 times.
22395 switch(door)
5654 {
5655 case dWALL:
5656 doortype=dt_wall;
5657 break;
5658
5659 case dWALK:
5660 doortype=dt_walk;
5661 break;
5662
5663 case dOPEN:
5664 12492 doortype=dt_pass;
5665 12492 break;
5666
5667 case dLOCKED:
5668 910 doortype=dt_lock;
5669 910 break;
5670
5671 case dUNLOCKED:
5672 1553 doortype=dt_olck;
5673 1553 break;
5674
5675 case dSHUTTER:
5676
3/4
✓ Branch 0 taken 2783 times.
✓ Branch 1 taken 409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2783 times.
3192 if(screenscrolling && ((HeroDir()^1)==side))
5677 {
5678 doortype=dt_osht;
5679 get_screen_state(scr->screen).open_doors = -4;
5680 break;
5681 }
5682
5683 [[fallthrough]];
5684 case d1WAYSHUTTER:
5685 3714 doortype=dt_shut;
5686 3714 break;
5687
5688 case dOPENSHUTTER:
5689 1694 doortype=dt_osht;
5690 1694 break;
5691
5692 case dBOSS:
5693 172 doortype=dt_boss;
5694 172 break;
5695
5696 case dOPENBOSS:
5697 67 doortype=dt_obos;
5698 67 break;
5699
5700 case dBOMBED:
5701 1138 doortype=dt_bomb;
5702 1138 break;
5703
5704 default:
5705 655 return;
5706 }
5707
5708
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5629 times.
✓ Branch 2 taken 5770 times.
✓ Branch 3 taken 5111 times.
✓ Branch 4 taken 5230 times.
21740 switch(side)
5709 {
5710 case up:
5711 5629 put_door(scr,nullptr,7,side,doortype,false,even_walls);
5712 5629 break;
5713
5714 case down:
5715 5770 put_door(scr,nullptr,151,side,doortype,false,even_walls);
5716 5770 break;
5717
5718 case left:
5719 5111 put_door(scr,nullptr,64,side,doortype,false,even_walls);
5720 5111 break;
5721
5722 case right:
5723 5230 put_door(scr,nullptr,78,side,doortype,false,even_walls);
5724 5230 break;
5725 }
5726 47568 }
5727
5728 6504 void putdoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t door, bool redraw, bool even_walls)
5729 {
5730 /*
5731 #define dWALL 0 // 000 0
5732 #define dBOMB 6 // 011 0
5733 #define 8 // 100 0
5734 enum {dt_pass=0, dt_lock, dt_shut, dt_boss, dt_olck, dt_osht, dt_obos, dt_wall, dt_bomb, dt_walk, dt_max};
5735 */
5736
5737
7/8
✓ Branch 0 taken 6504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6500 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6417 times.
✓ Branch 5 taken 83 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 6409 times.
6504 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5738 91 return;
5739
5740 int32_t doortype;
5741
5742
8/12
✓ Branch 0 taken 227 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 362 times.
✓ Branch 7 taken 1530 times.
✓ Branch 8 taken 3958 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 51 times.
✓ Branch 11 taken 231 times.
6413 switch(door)
5743 {
5744 case dWALL:
5745 doortype=dt_wall;
5746 break;
5747
5748 case dWALK:
5749 doortype=dt_walk;
5750 break;
5751
5752 case dOPEN:
5753 50 doortype=dt_pass;
5754 50 break;
5755
5756 case dLOCKED:
5757 doortype=dt_lock;
5758 break;
5759
5760 case dUNLOCKED:
5761 362 doortype=dt_olck;
5762 362 break;
5763
5764 case dSHUTTER:
5765
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1530 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1530 if(screenscrolling && ((HeroDir()^1)==side))
5766 {
5767 doortype=dt_osht;
5768 get_screen_state(cur_screen).open_doors = -4;
5769 break;
5770 }
5771
5772 [[fallthrough]];
5773 case d1WAYSHUTTER:
5774 1757 doortype=dt_shut;
5775 1757 break;
5776
5777 case dOPENSHUTTER:
5778 3958 doortype=dt_osht;
5779 3958 break;
5780
5781 case dBOSS:
5782 4 doortype=dt_boss;
5783 4 break;
5784
5785 case dOPENBOSS:
5786 51 doortype=dt_obos;
5787 51 break;
5788
5789 case dBOMBED:
5790 231 doortype=dt_bomb;
5791 231 break;
5792
5793 default:
5794 return;
5795 }
5796
5797
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1860 times.
✓ Branch 2 taken 1357 times.
✓ Branch 3 taken 1514 times.
✓ Branch 4 taken 1682 times.
6413 switch(side)
5798 {
5799 case up:
5800
2/2
✓ Branch 0 taken 1791 times.
✓ Branch 1 taken 69 times.
1860 switch(door)
5801 {
5802 case dBOMBED:
5803
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
138 if(redraw)
5804 {
5805 69 over_door(scr,dest,39,side,0,0);
5806 69 }
5807 [[fallthrough]];
5808 default:
5809 1860 put_door(scr,dest,7,side,doortype,redraw, even_walls);
5810 1860 break;
5811 }
5812
5813 1860 break;
5814
5815 case down:
5816
2/2
✓ Branch 0 taken 1318 times.
✓ Branch 1 taken 39 times.
1357 switch(door)
5817 {
5818 case dBOMBED:
5819
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if(redraw)
5820 {
5821 39 over_door(scr,dest,135,side,0,0);
5822 39 }
5823 [[fallthrough]];
5824 default:
5825 1357 put_door(scr,dest,151,side,doortype,redraw, even_walls);
5826 1357 break;
5827 }
5828
5829 1357 break;
5830
5831 case left:
5832
2/2
✓ Branch 0 taken 1463 times.
✓ Branch 1 taken 51 times.
1514 switch(door)
5833 {
5834 case dBOMBED:
5835
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 if(redraw)
5836 {
5837 51 over_door(scr,dest,66,side,0,0);
5838 51 }
5839 [[fallthrough]];
5840 default:
5841 1514 put_door(scr,dest,64,side,doortype,redraw, even_walls);
5842 1514 break;
5843 }
5844
5845 1514 break;
5846
5847 case right:
5848
2/2
✓ Branch 0 taken 1610 times.
✓ Branch 1 taken 72 times.
1682 switch(door)
5849 {
5850 case dBOMBED:
5851
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
144 if(redraw)
5852 {
5853 72 over_door(scr,dest,77,side,0,0);
5854 72 }
5855 [[fallthrough]];
5856 default:
5857 1682 put_door(scr,dest,78,side,doortype,redraw, even_walls);
5858 1682 break;
5859 }
5860
5861 1682 break;
5862 }
5863 6504 }
5864
5865 586 void putcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5866 {
5867
1/2
✓ Branch 0 taken 586 times.
✗ Branch 1 not taken.
586 if(combo!=0)
5868 {
5869 586 putcombo(dest,x, y, combo, cset);
5870 586 }
5871 586 }
5872
5873 293 void overcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5874 {
5875
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 74 times.
293 if(combo!=0)
5876 {
5877 219 overcombo(dest,x, y, combo, cset);
5878 219 }
5879 293 }
5880
5881 125 void showbombeddoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t offx, int32_t offy)
5882 {
5883 125 int32_t d = scr->door_combo_set;
5884
5885
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 37 times.
125 switch(side)
5886 {
5887 case up:
5888 86 putcombo_not_zero(dest,((7&15)<<4) + offx,(7&0xF0) + offy,
5889 43 DoorComboSets[d].doorcombo_u[dt_bomb][0],
5890 43 DoorComboSets[d].doorcset_u[dt_bomb][0]);
5891 86 putcombo_not_zero(dest,((8&15)<<4) + offx,(8&0xF0) + offy,
5892 43 DoorComboSets[d].doorcombo_u[dt_bomb][1],
5893 43 DoorComboSets[d].doorcset_u[dt_bomb][1]);
5894 86 putcombo_not_zero(dest,((23&15)<<4) + offx,(23&0xF0) + offy,
5895 43 DoorComboSets[d].doorcombo_u[dt_bomb][2],
5896 43 DoorComboSets[d].doorcset_u[dt_bomb][2]);
5897 86 putcombo_not_zero(dest,((24&15)<<4) + offx,(24&0xF0) + offy,
5898 43 DoorComboSets[d].doorcombo_u[dt_bomb][3],
5899 43 DoorComboSets[d].doorcset_u[dt_bomb][3]);
5900 86 overcombo_not_zero(dest,((39&15)<<4) + offx,(39&0xF0) + offy,
5901 43 DoorComboSets[d].bombdoorcombo_u[0],
5902 43 DoorComboSets[d].bombdoorcset_u[0]);
5903 86 overcombo_not_zero(dest,((40&15)<<4) + offx,(40&0xF0) + offy,
5904 43 DoorComboSets[d].bombdoorcombo_u[1],
5905 43 DoorComboSets[d].bombdoorcset_u[1]);
5906 43 break;
5907
5908 case down:
5909 78 putcombo_not_zero(dest,((151&15)<<4) + offx,(151&0xF0) + offy,
5910 39 DoorComboSets[d].doorcombo_d[dt_bomb][0],
5911 39 DoorComboSets[d].doorcset_d[dt_bomb][0]);
5912 78 putcombo_not_zero(dest,((152&15)<<4) + offx,(152&0xF0) + offy,
5913 39 DoorComboSets[d].doorcombo_d[dt_bomb][1],
5914 39 DoorComboSets[d].doorcset_d[dt_bomb][1]);
5915 78 putcombo_not_zero(dest,((167&15)<<4) + offx,(167&0xF0) + offy,
5916 39 DoorComboSets[d].doorcombo_d[dt_bomb][2],
5917 39 DoorComboSets[d].doorcset_d[dt_bomb][2]);
5918 78 putcombo_not_zero(dest,((168&15)<<4) + offx,(168&0xF0) + offy,
5919 39 DoorComboSets[d].doorcombo_d[dt_bomb][3],
5920 39 DoorComboSets[d].doorcset_d[dt_bomb][3]);
5921 78 overcombo_not_zero(dest,((135&15)<<4) + offx,(135&0xF0) + offy,
5922 39 DoorComboSets[d].bombdoorcombo_d[0],
5923 39 DoorComboSets[d].bombdoorcset_d[0]);
5924 78 overcombo_not_zero(dest,((136&15)<<4) + offx,(136&0xF0) + offy,
5925 39 DoorComboSets[d].bombdoorcombo_d[1],
5926 39 DoorComboSets[d].bombdoorcset_d[1]);
5927 39 break;
5928
5929 case left:
5930 12 putcombo_not_zero(dest,((64&15)<<4) + offx,(64&0xF0) + offy,
5931 6 DoorComboSets[d].doorcombo_l[dt_bomb][0],
5932 6 DoorComboSets[d].doorcset_l[dt_bomb][0]);
5933 12 putcombo_not_zero(dest,((65&15)<<4) + offx,(65&0xF0) + offy,
5934 6 DoorComboSets[d].doorcombo_l[dt_bomb][1],
5935 6 DoorComboSets[d].doorcset_l[dt_bomb][1]);
5936 12 putcombo_not_zero(dest,((80&15)<<4) + offx,(80&0xF0) + offy,
5937 6 DoorComboSets[d].doorcombo_l[dt_bomb][2],
5938 6 DoorComboSets[d].doorcset_l[dt_bomb][2]);
5939 12 putcombo_not_zero(dest,((81&15)<<4) + offx,(81&0xF0) + offy,
5940 6 DoorComboSets[d].doorcombo_l[dt_bomb][3],
5941 6 DoorComboSets[d].doorcset_l[dt_bomb][3]);
5942 12 putcombo_not_zero(dest,((96&15)<<4) + offx,(96&0xF0) + offy,
5943 6 DoorComboSets[d].doorcombo_l[dt_bomb][4],
5944 6 DoorComboSets[d].doorcset_l[dt_bomb][4]);
5945 12 putcombo_not_zero(dest,((97&15)<<4) + offx,(97&0xF0) + offy,
5946 6 DoorComboSets[d].doorcombo_l[dt_bomb][5],
5947 6 DoorComboSets[d].doorcset_l[dt_bomb][5]);
5948 12 overcombo_not_zero(dest,((66&15)<<4) + offx,(66&0xF0) + offy,
5949 6 DoorComboSets[d].bombdoorcombo_l[0],
5950 6 DoorComboSets[d].bombdoorcset_l[0]);
5951 12 overcombo_not_zero(dest,((82&15)<<4) + offx,(82&0xF0) + offy,
5952 6 DoorComboSets[d].bombdoorcombo_l[1],
5953 6 DoorComboSets[d].bombdoorcset_l[1]);
5954 12 overcombo_not_zero(dest,((98&15)<<4) + offx,(98&0xF0) + offy,
5955 6 DoorComboSets[d].bombdoorcombo_l[2],
5956 6 DoorComboSets[d].bombdoorcset_l[2]);
5957 6 break;
5958
5959 case right:
5960 74 putcombo_not_zero(dest,((78&15)<<4) + offx,(78&0xF0) + offy,
5961 37 DoorComboSets[d].doorcombo_r[dt_bomb][0],
5962 37 DoorComboSets[d].doorcset_r[dt_bomb][0]);
5963 74 putcombo_not_zero(dest,((79&15)<<4) + offx,(79&0xF0) + offy,
5964 37 DoorComboSets[d].doorcombo_r[dt_bomb][1],
5965 37 DoorComboSets[d].doorcset_r[dt_bomb][1]);
5966 74 putcombo_not_zero(dest,((94&15)<<4) + offx,(94&0xF0) + offy,
5967 37 DoorComboSets[d].doorcombo_r[dt_bomb][2],
5968 37 DoorComboSets[d].doorcset_r[dt_bomb][2]);
5969 74 putcombo_not_zero(dest,((95&15)<<4) + offx,(95&0xF0) + offy,
5970 37 DoorComboSets[d].doorcombo_r[dt_bomb][3],
5971 37 DoorComboSets[d].doorcset_r[dt_bomb][3]);
5972 74 putcombo_not_zero(dest,((110&15)<<4) + offx,(110&0xF0) + offy,
5973 37 DoorComboSets[d].doorcombo_r[dt_bomb][4],
5974 37 DoorComboSets[d].doorcset_r[dt_bomb][4]);
5975 74 putcombo_not_zero(dest,((111&15)<<4) + offx,(111&0xF0) + offy,
5976 37 DoorComboSets[d].doorcombo_r[dt_bomb][5],
5977 37 DoorComboSets[d].doorcset_r[dt_bomb][5]);
5978 74 overcombo_not_zero(dest,((77&15)<<4) + offx,(77&0xF0) + offy,
5979 37 DoorComboSets[d].bombdoorcombo_r[0],
5980 37 DoorComboSets[d].bombdoorcset_r[0]);
5981 74 overcombo_not_zero(dest,((93&15)<<4) + offx,(93&0xF0) + offy,
5982 37 DoorComboSets[d].bombdoorcombo_r[1],
5983 37 DoorComboSets[d].bombdoorcset_r[1]);
5984 74 overcombo_not_zero(dest,((109&15)<<4) + offx,(109&0xF0) + offy,
5985 37 DoorComboSets[d].bombdoorcombo_r[2],
5986 37 DoorComboSets[d].bombdoorcset_r[2]);
5987 37 break;
5988 }
5989 125 }
5990
5991 5526332 void openshutters(mapscr* scr)
5992 {
5993 5526332 bool opened_door = false;
5994
2/2
✓ Branch 0 taken 5526332 times.
✓ Branch 1 taken 22105328 times.
27631660 for(int32_t i=0; i<4; i++)
5995
2/2
✓ Branch 0 taken 22101370 times.
✓ Branch 1 taken 3958 times.
22109286 if(scr->door[i]==dSHUTTER)
5996 {
5997 3958 putdoor(scr, scrollbuf, i, dOPENSHUTTER);
5998 3958 scr->door[i]=dOPENSHUTTER;
5999 3958 opened_door = true;
6000 3958 }
6001
6002 5526332 auto& combo_cache = combo_caches::shutter;
6003 2221802210 for_every_combo_in_screen(create_screen_handles(scr), [&](const auto& handle) {
6004
3/4
✓ Branch 0 taken 2214353321 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1922550 times.
✗ Branch 3 not taken.
2216275878 if (!combo_cache.minis[handle.data()].shutter)
6005 2216275871 return;
6006
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
6007 7 return trig.trigger_flags.get(TRIGFLAG_SHUTTER);
6008 });
6009 2216275878 });
6010
6011
2/2
✓ Branch 0 taken 5523601 times.
✓ Branch 1 taken 2731 times.
5526332 if(opened_door)
6012 2731 sfx(WAV_DOOR);
6013 5526332 }
6014
6015 15709541 void clear_darkroom_bitmaps()
6016 {
6017 15709541 clear_to_color(darkscr_bmp, game->get_darkscr_color());
6018 15709541 clear_to_color(darkscr_bmp_trans, game->get_darkscr_color());
6019 15709541 }
6020
6021 16737377 bool is_dark(const mapscr* scr)
6022 {
6023 16737377 bool dark = scr->flags&fDARK;
6024
2/2
✓ Branch 0 taken 3722 times.
✓ Branch 1 taken 16733655 times.
16737377 if (region_is_lit) return !dark;
6025 16733655 return dark;
6026 16737377 }
6027
6028 53189 bool scrolling_is_dark(const mapscr* scr)
6029 {
6030 53189 bool dark = scr->flags&fDARK;
6031
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 53187 times.
53189 if (scrolling_region_is_lit) return !dark;
6032 53187 return dark;
6033 53189 }
6034
6035 38431 bool is_any_dark()
6036 {
6037 38431 bool dark = false;
6038 78118 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
6039 39687 dark |= (bool)(is_dark(scr));
6040 39687 });
6041 38431 return dark;
6042 }
6043
6044
3/4
✓ Branch 0 taken 2968 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2544 times.
✓ Branch 3 taken 424 times.
2968 static mapscr prev_origin_scrs[7];
6045 424 static std::set<int> loadscr_ffc_script_ids_to_remove;
6046
6047 static void handle_screen_overlay(const std::vector<mapscr*>& screens)
6048 {
6049 mapscr* base_scr = screens[0];
6050 mapscr* previous_scr = &prev_origin_scrs[0];
6051
6052 for (int i = 0; i < 176; i++)
6053 {
6054 if (base_scr->data[i] == 0)
6055 {
6056 base_scr->data[i] = previous_scr->data[i];
6057 base_scr->sflag[i] = previous_scr->sflag[i];
6058 base_scr->cset[i] = previous_scr->cset[i];
6059 }
6060 }
6061
6062 for (int i = 0; i < 6; i++)
6063 {
6064 if (previous_scr->layermap[i] > 0 && base_scr->layermap[i] > 0)
6065 {
6066 int lm = (base_scr->layermap[i]-1)*MAPSCRS+base_scr->layerscreen[i];
6067 int fm = (previous_scr->layermap[i]-1)*MAPSCRS+previous_scr->layerscreen[i];
6068
6069 for (int j = 0; j < 176; j++)
6070 {
6071 if (TheMaps[lm].data[j] == 0)
6072 {
6073 TheMaps[lm].data[j] = TheMaps[fm].data[j];
6074 TheMaps[lm].sflag[j] = TheMaps[fm].sflag[j];
6075 TheMaps[lm].cset[j] = TheMaps[fm].cset[j];
6076 }
6077 }
6078 }
6079 }
6080
6081 for (int i = 1; i <= 6; i++)
6082 {
6083 mapscr* scr = screens[i];
6084 previous_scr = &prev_origin_scrs[i];
6085
6086 if (scr->layermap[i] > 0)
6087 {
6088 for (int y = 0; y < 11; y++)
6089 {
6090 for (int x = 0; x < 16; x++)
6091 {
6092 int c = y*16+x;
6093
6094 if (scr->data[c]==0)
6095 {
6096 scr->data[c] = previous_scr->data[c];
6097 scr->sflag[c] = previous_scr->sflag[c];
6098 scr->cset[c] = previous_scr->cset[c];
6099 }
6100 }
6101 }
6102 }
6103 }
6104 }
6105
6106 38771 static void load_a_screen_and_layers_init(int dmap, int screen, int ldir, bool screen_overlay, bool ffc_overlay)
6107 {
6108 38771 std::vector<mapscr*> screens;
6109
6110
1/2
✓ Branch 0 taken 38771 times.
✗ Branch 1 not taken.
38771 const mapscr* source = get_canonical_scr(cur_map, screen);
6111
2/4
✓ Branch 0 taken 38771 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38771 times.
✗ Branch 3 not taken.
38771 mapscr* base_scr = new mapscr(*source);
6112 38771 temporary_screens[screen*7] = base_scr;
6113
1/2
✓ Branch 0 taken 38771 times.
✗ Branch 1 not taken.
38771 screens.push_back(base_scr);
6114
6115 38771 base_scr->valid |= mVALID; // layer 0 is always valid
6116
6117
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 37527 times.
38771 if (screen == cur_screen)
6118 37527 origin_scr = base_scr;
6119
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 37527 times.
38771 if (screen == Hero.current_screen)
6120 37527 hero_scr = prev_hero_scr = base_scr;
6121
6122
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 38627 times.
38771 if (source->script > 0)
6123
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6124
6125
2/2
✓ Branch 0 taken 38771 times.
✓ Branch 1 taken 232626 times.
271397 for (int i = 0; i < 6; i++)
6126 {
6127
2/2
✓ Branch 0 taken 176157 times.
✓ Branch 1 taken 56469 times.
232626 if(source->layermap[i]>0)
6128 {
6129
3/6
✓ Branch 0 taken 56469 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56469 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 56469 times.
✗ Branch 5 not taken.
56469 mapscr* layer_scr = new mapscr(*get_canonical_scr(source->layermap[i]-1, source->layerscreen[i]));
6130 56469 layer_scr->map = cur_map;
6131 56469 layer_scr->screen = screen;
6132 56469 layer_scr->valid |= mVALID;
6133
1/2
✓ Branch 0 taken 56469 times.
✗ Branch 1 not taken.
56469 screens.push_back(layer_scr);
6134 56469 }
6135 else
6136 {
6137
2/4
✓ Branch 0 taken 176157 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 176157 times.
✗ Branch 3 not taken.
176157 mapscr* layer_scr = new mapscr();
6138 176157 layer_scr->map = cur_map;
6139 176157 layer_scr->screen = screen;
6140
1/2
✓ Branch 0 taken 176157 times.
✗ Branch 1 not taken.
176157 screens.push_back(layer_scr);
6141 }
6142 232626 temporary_screens[screen*7+i+1] = screens[i+1];
6143 232626 }
6144
6145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38771 times.
38771 if (screen_overlay)
6146 handle_screen_overlay(screens);
6147
6148
2/2
✓ Branch 0 taken 145 times.
✓ Branch 1 taken 38626 times.
38771 if (ffc_overlay)
6149 {
6150 145 mapscr* previous_scr = &prev_origin_scrs[0];
6151
1/2
✓ Branch 0 taken 145 times.
✗ Branch 1 not taken.
145 int num_ffcs = previous_scr->numFFC();
6152
2/2
✓ Branch 0 taken 4640 times.
✓ Branch 1 taken 145 times.
4785 for (int i = 0; i < num_ffcs; i++)
6153 {
6154
2/2
✓ Branch 0 taken 4365 times.
✓ Branch 1 taken 275 times.
4640 if ((previous_scr->ffcs[i].flags&ffc_carryover))
6155 {
6156
2/4
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 275 times.
✗ Branch 3 not taken.
275 auto& ffc = base_scr->getFFC(i) = previous_scr->ffcs[i];
6157 275 ffc.screen_spawned = screen;
6158
6159
1/2
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
275 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + i;
6160
1/2
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
275 loadscr_ffc_script_ids_to_remove.erase(ffc_id);
6161
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 275 times.
275 if (previous_scr->ffcs[i].flags&ffc_scriptreset)
6162 {
6163 FFCore.reset_script_engine_data(ScriptType::FFC, ffc_id);
6164 }
6165 275 }
6166 4640 }
6167 145 }
6168
6169
1/2
✓ Branch 0 taken 38771 times.
✗ Branch 1 not taken.
1145562 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6170
1/2
✓ Branch 0 taken 38771 times.
✗ Branch 1 not taken.
38771 int num_ffcs = base_scr->numFFC();
6171
2/2
✓ Branch 0 taken 1106791 times.
✓ Branch 1 taken 38771 times.
1145562 for (word i = 0; i < num_ffcs; i++)
6172 {
6173 1106791 base_scr->ffcs[i].screen_spawned = screen;
6174
1/2
✓ Branch 0 taken 1106791 times.
✗ Branch 1 not taken.
1106791 base_scr->ffcs[i].x += offx;
6175
1/2
✓ Branch 0 taken 1106791 times.
✗ Branch 1 not taken.
1106791 base_scr->ffcs[i].y += offy;
6176 1106791 }
6177 38771 }
6178
6179 38771 static void load_a_screen_and_layers_post(int dmap, int screen, int ldir)
6180 {
6181 38771 mapscr* base_scr = get_scr(screen);
6182 38771 int mi = mapind(cur_map, screen);
6183
6184 // Apply perm secrets, if applicable.
6185
2/2
✓ Branch 0 taken 11520 times.
✓ Branch 1 taken 27251 times.
38771 if (canPermSecret(dmap, screen))
6186 {
6187
2/2
✓ Branch 0 taken 24345 times.
✓ Branch 1 taken 2906 times.
27251 if(game->maps[mi] & mSECRET) // if special stuff done before
6188 {
6189 2906 reveal_hidden_stairs(base_scr, screen, false);
6190 2906 trigger_secrets_for_screen(TriggerSource::SecretsScreenState, base_scr, false);
6191 2906 }
6192
2/2
✓ Branch 0 taken 27248 times.
✓ Branch 1 taken 3 times.
27251 if(game->maps[mi] & mLIGHTBEAM) // if special stuff done before
6193 {
6194
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (int layer = 0; layer <= 6; layer++)
6195 {
6196 21 mapscr* layer_scr = get_scr_layer(screen, layer);
6197
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 21 times.
3717 for (int pos = 0; pos < 176; pos++)
6198 {
6199 3696 newcombo const* cmb = &combobuf[layer_scr->data[pos]];
6200
2/2
✓ Branch 0 taken 3693 times.
✓ Branch 1 taken 3 times.
3696 if(cmb->type == cLIGHTTARGET)
6201 {
6202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(cmb->usrflags&cflag1)) //Unlit version
6203 {
6204 3 layer_scr->data[pos] += 1;
6205 3 }
6206 3 }
6207 3696 }
6208 21 }
6209 3 }
6210 27251 }
6211
6212 38771 auto screen_handles = create_screen_handles(base_scr);
6213
6214 38771 int destlvl = DMaps[dmap].level;
6215 38771 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6216 38771 toggle_gswitches_load(screen_handles);
6217
6218 38771 bool should_check_for_state_things = (screen < 0x80);
6219
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 37864 times.
38771 if (should_check_for_state_things)
6220 {
6221
2/2
✓ Branch 0 taken 37430 times.
✓ Branch 1 taken 434 times.
37864 if (game->maps[mi]&mLOCKBLOCK)
6222 434 remove_lockblocks(screen_handles);
6223
2/2
✓ Branch 0 taken 37775 times.
✓ Branch 1 taken 89 times.
37864 if (game->maps[mi]&mBOSSLOCKBLOCK)
6224 89 remove_bosslockblocks(screen_handles);
6225
2/2
✓ Branch 0 taken 37696 times.
✓ Branch 1 taken 168 times.
37864 if (game->maps[mi]&mCHEST)
6226 168 remove_chests(screen_handles);
6227
1/2
✓ Branch 0 taken 37864 times.
✗ Branch 1 not taken.
37864 if (game->maps[mi]&mLOCKEDCHEST)
6228 remove_lockedchests(screen_handles);
6229
2/2
✓ Branch 0 taken 37853 times.
✓ Branch 1 taken 11 times.
37864 if (game->maps[mi]&mBOSSCHEST)
6230 11 remove_bosschests(screen_handles);
6231
6232 37864 clear_xdoors_mi(screen_handles, mi, true);
6233 37864 clear_xstatecombos_mi(screen_handles, mi, true);
6234 37864 }
6235
6236 // check doors
6237
2/2
✓ Branch 0 taken 27250 times.
✓ Branch 1 taken 11521 times.
38771 if (isdungeon(dmap, screen))
6238 {
6239
2/2
✓ Branch 0 taken 46084 times.
✓ Branch 1 taken 11521 times.
57605 for(int32_t i=0; i<4; i++)
6240 {
6241 46084 int32_t door=base_scr->door[i];
6242
6243
5/5
✓ Branch 0 taken 5303 times.
✓ Branch 1 taken 36475 times.
✓ Branch 2 taken 2372 times.
✓ Branch 3 taken 230 times.
✓ Branch 4 taken 1704 times.
46084 switch(door)
6244 {
6245 case d1WAYSHUTTER:
6246 case dSHUTTER:
6247
3/4
✓ Branch 0 taken 1694 times.
✓ Branch 1 taken 3609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1694 times.
5303 if ((ldir^1)==i && screen == Hero.current_screen)
6248 {
6249 1694 base_scr->door[i]=dOPENSHUTTER;
6250 1694 }
6251
6252 5303 get_screen_state(screen).open_doors = -4;
6253 5303 break;
6254
6255 case dLOCKED:
6256
3/4
✓ Branch 0 taken 2372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1473 times.
✓ Branch 3 taken 899 times.
2372 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6257 {
6258 1473 base_scr->door[i]=dUNLOCKED;
6259 1473 }
6260
6261 2372 break;
6262
6263 case dBOSS:
6264
3/4
✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 168 times.
230 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6265 {
6266 62 base_scr->door[i]=dOPENBOSS;
6267 62 }
6268
6269 230 break;
6270
6271 case dBOMB:
6272
3/4
✓ Branch 0 taken 1704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1087 times.
✓ Branch 3 taken 617 times.
1704 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6273 {
6274 1087 base_scr->door[i]=dBOMBED;
6275 1087 }
6276
6277 1704 break;
6278 }
6279
6280 46084 update_door(base_scr, i, base_scr->door[i]);
6281
6282
4/4
✓ Branch 0 taken 41517 times.
✓ Branch 1 taken 4567 times.
✓ Branch 2 taken 736 times.
✓ Branch 3 taken 40781 times.
46084 if(door==dSHUTTER||door==d1WAYSHUTTER)
6283 {
6284 5303 base_scr->door[i]=door;
6285 5303 }
6286 46084 }
6287 11521 }
6288
6289
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 38632 times.
38771 if (!(base_scr->flags3 & fCYCLEONINIT))
6290 38632 return;
6291
6292
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 973 times.
1112 for (int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6293 {
6294
4/4
✓ Branch 0 taken 834 times.
✓ Branch 1 taken 139 times.
✓ Branch 2 taken 383 times.
✓ Branch 3 taken 451 times.
973 if (j<0 || base_scr->layermap[j] > 0)
6295 {
6296 522 mapscr* layer_scr = get_scr_layer(screen, j + 1);
6297
3/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 139 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 383 times.
522 mapscr* layerscreen= (j<0 ? base_scr : layer_scr->valid ? layer_scr :
6298 &TheMaps[(base_scr->layermap[j]-1)*MAPSCRS]+base_scr->layerscreen[j]);
6299
6300
2/2
✓ Branch 0 taken 91872 times.
✓ Branch 1 taken 522 times.
92394 for(int32_t i=0; i<176; ++i)
6301 {
6302 91872 int32_t c=layerscreen->data[i];
6303
6304 // New screen flag: Cycle Combos At Screen Init
6305
5/6
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 91807 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
91872 if(combobuf[c].nextcombo != 0 && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6306 {
6307 65 int32_t r = 0;
6308
6309
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 65 times.
149 while(combobuf[c].can_cycle() && r++ < 10)
6310 {
6311 84 newcombo const& cmb = combobuf[c];
6312 84 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6313
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6314 84 layerscreen->data[i] = cid;
6315
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 69 times.
84 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6317 84 c = layerscreen->data[i];
6318 }
6319 65 }
6320 91872 }
6321 522 }
6322 973 }
6323 38771 }
6324
6325 // Set `cur_screen` to `screen` and load new screens into temporary memory.
6326 //
6327 // Called anytime a player moves to a new screen (either via warping, scrolling, continue, starting
6328 // the game, etc...)
6329 //
6330 // Note: for regions, only the initial screen load calls this function. Simply walking between
6331 // screens in the same region does not use this, because every screen in a region is loaded into
6332 // temporary memory up front.
6333 //
6334 // If scr >= 0x80, `Hero.current_screen` will be saved to `home_screen` and also be loaded into
6335 // `special_warp_return_scr`.
6336 //
6337 // If origin_screen_overlay is true, the old origin_scr combos will be copied to the new origin_scr combos
6338 // on all layers (but only where the new screen has a 0 combo).
6339 //
6340 // TODO: loadscr should set curdmap, but currently callers do that.
6341 37527 void loadscr(int32_t destdmap, int32_t screen, int32_t ldir, bool origin_screen_overlay, bool no_x80_dir)
6342 {
6343 37527 zapp_reporting_set_tag("screen", screen);
6344
2/2
✓ Branch 0 taken 9307 times.
✓ Branch 1 taken 28220 times.
37527 if (destdmap != -1)
6345 9307 zapp_reporting_set_tag("dmap", destdmap);
6346
6347 37527 int32_t orig_destdmap = destdmap;
6348
2/2
✓ Branch 0 taken 9307 times.
✓ Branch 1 taken 28220 times.
37527 if (destdmap < 0) destdmap = cur_dmap;
6349
6350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37527 times.
37527 if (replay_is_active())
6351 {
6352
2/2
✓ Branch 0 taken 28220 times.
✓ Branch 1 taken 9307 times.
37527 if (orig_destdmap != -1)
6353 {
6354
2/2
✓ Branch 0 taken 8237 times.
✓ Branch 1 taken 1070 times.
9307 if (strlen(DMaps[orig_destdmap].name) > 0)
6355 {
6356
1/2
✓ Branch 0 taken 8237 times.
✗ Branch 1 not taken.
8237 replay_step_comment(fmt::format("dmap={} {}", orig_destdmap, DMaps[orig_destdmap].name));
6357 8237 }
6358 else
6359 {
6360
1/2
✓ Branch 0 taken 1070 times.
✗ Branch 1 not taken.
1070 replay_step_comment(fmt::format("dmap={}", orig_destdmap));
6361 }
6362 9307 }
6363 37527 replay_step_comment_loadscr(screen);
6364
6365 // Reset the rngs and frame count so that recording steps can be modified without impacting
6366 // behavior of later screens.
6367 37527 replay_sync_rng();
6368 37527 }
6369
6370
2/2
✓ Branch 0 taken 1754087 times.
✓ Branch 1 taken 37527 times.
1791614 for (auto& state : get_screen_states())
6371 1754087 state.second.triggered_secrets = false;
6372 37527 slopes.clear();
6373 37527 Hero.clear_platform_ffc();
6374 37527 timeExitAllGenscript(GENSCR_ST_CHANGE_SCREEN);
6375 37527 clear_darkroom_bitmaps();
6376 37527 msgscr = nullptr;
6377
6378
2/2
✓ Branch 0 taken 52507405 times.
✓ Branch 1 taken 37527 times.
52544932 for (word x=0; x<animated_combos; x++)
6379 {
6380
2/2
✓ Branch 0 taken 21102247 times.
✓ Branch 1 taken 31405158 times.
52507405 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6381 {
6382 21102247 combobuf[animated_combo_table4[x][0]].aclk = 0;
6383 21102247 }
6384 52507405 }
6385 37527 reset_combo_animations2();
6386 37527 region_is_lit = false;
6387
6388 // Legacy features (combo and ffc overlays) may need the previous origin screens during loading
6389 // of the new ones.
6390 37527 bool origin_ffc_overlay = false;
6391
2/2
✓ Branch 0 taken 1167 times.
✓ Branch 1 taken 36360 times.
37527 if (origin_scr)
6392 {
6393
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 36358 times.
36360 if (!(origin_scr->flags5&fNOFFCARRYOVER))
6394 {
6395 36358 int c = origin_scr->numFFC();
6396
2/2
✓ Branch 0 taken 36213 times.
✓ Branch 1 taken 1040673 times.
1076886 for (int i = 0; i < c; i++)
6397 {
6398
2/2
✓ Branch 0 taken 1040528 times.
✓ Branch 1 taken 145 times.
1040673 if (origin_scr->ffcs[i].flags&ffc_carryover)
6399 {
6400 145 origin_ffc_overlay = true;
6401 145 break;
6402 }
6403 1040528 }
6404 36358 }
6405
6406
3/4
✓ Branch 0 taken 36360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 145 times.
✓ Branch 3 taken 36215 times.
36360 if (origin_screen_overlay || origin_ffc_overlay)
6407 {
6408
2/2
✓ Branch 0 taken 1015 times.
✓ Branch 1 taken 145 times.
1160 for (int i = 0; i <= 6; i++)
6409 {
6410 1015 mapscr* prev_scr = get_scr_layer(cur_screen, i);
6411
1/2
✓ Branch 0 taken 1015 times.
✗ Branch 1 not taken.
1015 if (prev_scr)
6412 1015 prev_origin_scrs[i] = *prev_scr;
6413 else
6414 prev_origin_scrs[i] = {};
6415 1015 }
6416 145 }
6417 36360 }
6418
6419 // When loading a new screen, all previous FFC scripts end, with one exception.
6420 // Based on origin_ffc_overlay, some ffc scripts don't get reset. This set starts with all of
6421 // them, but scripts that need their data to persist will be removed.
6422 37527 loadscr_ffc_script_ids_to_remove.clear();
6423
2/2
✓ Branch 0 taken 83196280 times.
✓ Branch 1 taken 37527 times.
83233807 for (auto& key : scriptEngineDatas | std::views::keys)
6424 {
6425
2/2
✓ Branch 0 taken 82065327 times.
✓ Branch 1 taken 1130953 times.
83196280 if (key.first == ScriptType::FFC)
6426 1130953 loadscr_ffc_script_ids_to_remove.insert(key.second);
6427 }
6428
6429 37527 load_region(destdmap, screen);
6430
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 36620 times.
37527 home_screen = screen >= 0x80 ? Hero.current_screen : cur_screen;
6431 37527 Hero.current_screen = screen;
6432
6433 37527 cpos_clear_all();
6434 37527 FFCore.destroyScriptableObjectsOfType(ScriptType::Screen);
6435 37527 FFCore.clear_combo_scripts();
6436
6437
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 37363 times.
37527 if (is_in_scrolling_region())
6438 {
6439
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6440 {
6441
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6442 {
6443
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool screen_overlay = origin_screen_overlay && screen == cur_screen;
6444
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool ffc_overlay = origin_ffc_overlay && screen == cur_screen;
6445 1408 load_a_screen_and_layers_init(destdmap, screen, ldir, screen_overlay, ffc_overlay);
6446 1408 }
6447 20992 }
6448 164 }
6449 else
6450 {
6451 37363 load_a_screen_and_layers_init(destdmap, screen, ldir, origin_screen_overlay, origin_ffc_overlay);
6452 }
6453
6454 37527 prepare_current_region_handles();
6455
6456
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 37363 times.
37527 if (is_in_scrolling_region())
6457 {
6458
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6459 {
6460
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6461 {
6462 1408 load_a_screen_and_layers_post(destdmap, screen, ldir);
6463 1408 }
6464 20992 }
6465 164 }
6466 else
6467 {
6468 37363 load_a_screen_and_layers_post(destdmap, screen, ldir);
6469 }
6470
6471 // If on a special screen, load the screen the player is currently on (home_screen) into special_warp_return_scr.
6472
2/2
✓ Branch 0 taken 36620 times.
✓ Branch 1 taken 907 times.
37527 if (screen >= 0x80)
6473
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 431 times.
907 loadscr_old(orig_destdmap, home_screen, no_x80_dir ? -1 : ldir, origin_screen_overlay);
6474
6475 37527 update_slope_comboposes();
6476 37527 cpos_force_update();
6477 37527 trig_trigger_groups();
6478
6479
2/2
✓ Branch 0 taken 1130678 times.
✓ Branch 1 taken 37527 times.
1168205 for (int index : loadscr_ffc_script_ids_to_remove)
6480 {
6481 // Note: ideally would use "destroySprite", but during scrolling the previous
6482 // screen's FFCs are still accessible (even though only the new screen's FFC scripts run).
6483 // The only difference is a call to "release_sprite_owned_objects". To defer FFC script
6484 // owned objects being released until the end of the scroll, here "destroyScriptableObject"
6485 // is used instead.
6486 //
6487 // So when is "release_sprite_owned_objects" called for FFCs? For scrolling screen
6488 // transitions, it's at the end of "scrollscr" via "delete_temporary_screens". Otherwise,
6489 // it is called above when "load_region" calls "clear_temporary_screens".
6490 1130678 FFCore.destroyScriptableObject(ScriptType::FFC, index);
6491 }
6492
6493 // "extended height mode" includes the top 56 pixels as part of the visible mapscr viewport,
6494 // allowing for regions to display 4 more rows of combos (as many as ALTTP does). This part of
6495 // screen is normally reserved for the passive subscreen, but in this mode mapscr combos are drawn below it.
6496 // It is up to the quest designer to make their subscreen be actually transparent.
6497 //
6498 // When not in "extended height mode" (otherwise 56 is 0):
6499 // - playing_field_offset: 56, but changes during earthquakes
6500 // - original_playing_field_offset: always 56
6501 //
6502 // These values are used to adjust where things are drawn on screen to account for the passive subscreen. Examples:
6503 // - yofs of sprites
6504 // - bitmap y offsets in draw_screen
6505 // - drawing offsets for putscr, do_layer
6506 // - drawing offsets for various calls to overtile16 (see bomb weapon explosion)
6507 // - lots more
6508 //
6509 // TODO: consider refactor of yofs, make yofs start as 0 by default and add playing_field_offset at draw time?
6510
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 37385 times.
37527 if (is_extended_height_mode())
6511 {
6512 142 playing_field_offset = 0;
6513 142 original_playing_field_offset = 0;
6514 // A few sprites exist as globals, so we must manually reset them.
6515 142 Hero.yofs = 0;
6516 142 mblock2.yofs = 0;
6517 142 }
6518 else
6519 {
6520 37385 mblock2.yofs = Hero.yofs = playing_field_offset = 56;
6521 37385 original_playing_field_offset = 56;
6522 }
6523 37527 is_any_room_dark = is_any_dark();
6524
6525 37527 game->load_portal();
6526 37527 throwGenScriptEvent(GENSCR_EVENT_CHANGE_SCREEN);
6527
3/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 37492 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
37527 if (Hero.lift_wpn && get_qr(qr_CARRYABLE_NO_ACROSS_SCREEN))
6528 {
6529 delete Hero.lift_wpn;
6530 Hero.lift_wpn = nullptr;
6531 }
6532
6533 37527 enemy_spawning_has_checked_been_here = false;
6534 37527 markBmap(-1, Hero.current_screen);
6535 37527 Hero.maybe_begin_advanced_maze();
6536 37527 }
6537
6538 // Don't use this directly! Use `loadscr` instead.
6539 907 void loadscr_old(int32_t destdmap, int32_t screen,int32_t ldir,bool overlay)
6540 {
6541
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int32_t destlvl = DMaps[destdmap < 0 ? cur_dmap : destdmap].level;
6542
6543 907 mapscr previous_scr = *special_warp_return_scr;
6544 907 mapscr* scr = special_warp_return_scr;
6545
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 const mapscr* source = get_canonical_scr(cur_map, screen);
6546
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 *scr = *source;
6547
6548
2/2
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 907 times.
6349 for (int i = 1; i <= 6; i++)
6549 {
6550
2/2
✓ Branch 0 taken 5059 times.
✓ Branch 1 taken 383 times.
5442 if (scr->layermap[i-1] > 0)
6551
2/4
✓ Branch 0 taken 383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
383 special_warp_return_scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6552 else
6553
2/4
✓ Branch 0 taken 5059 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5059 times.
✗ Branch 3 not taken.
5059 special_warp_return_scrs[i] = {};
6554 5442 }
6555
6556 907 scr->valid |= mVALID; //layer 0 is always valid
6557
6558
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 907 times.
907 if ( source->script > 0 )
6559 {
6560 scr->script = source->script;
6561 for ( int32_t q = 0; q < 8; q++ )
6562 {
6563 scr->screeninitd[q] = source->screeninitd[q];
6564 }
6565 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6566 }
6567 else
6568 {
6569 907 scr->script = 0;
6570 }
6571
6572
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 if(overlay)
6573 {
6574 for(int32_t c=0; c< 176; ++c)
6575 {
6576 if(scr->data[c]==0)
6577 {
6578 scr->data[c]=previous_scr.data[c];
6579 scr->sflag[c]=previous_scr.sflag[c];
6580 scr->cset[c]=previous_scr.cset[c];
6581 }
6582 }
6583
6584 for(int32_t i=0; i<6; i++)
6585 {
6586 if(previous_scr.layermap[i]>0 && scr->layermap[i]>0)
6587 {
6588 int32_t lm = (scr->layermap[i]-1)*MAPSCRS+scr->layerscreen[i];
6589 int32_t fm = (previous_scr.layermap[i]-1)*MAPSCRS+previous_scr.layerscreen[i];
6590
6591 for(int32_t c=0; c< 176; ++c)
6592 {
6593 if(TheMaps[lm].data[c]==0)
6594 {
6595 TheMaps[lm].data[c] = TheMaps[fm].data[c];
6596 TheMaps[lm].sflag[c] = TheMaps[fm].sflag[c];
6597 TheMaps[lm].cset[c] = TheMaps[fm].cset[c];
6598 }
6599 }
6600 }
6601 }
6602 }
6603
6604
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
29900 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6605
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int c = scr->numFFC();
6606
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 28993 times.
29900 for (word i = 0; i < c; i++)
6607 {
6608 28993 scr->ffcs[i].screen_spawned = screen;
6609
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].x += offx;
6610
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].y += offy;
6611 28993 }
6612
6613 907 int mi = mapind(cur_map, screen);
6614
6615 // Apply perm secrets, if applicable.
6616
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if(canPermSecret(destdmap,screen))
6617 {
6618
3/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 332 times.
536 if(game->maps[mi]&mSECRET) // if special stuff done before
6619 {
6620
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 reveal_hidden_stairs(scr, screen, false);
6621
6622
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
6623
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 get_screen_state(special_warp_return_scr->screen).triggered_secrets = true;
6624 204 bool do_replay_comment = true;
6625 204 bool from_active_screen = false;
6626
2/4
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✗ Branch 3 not taken.
204 trigger_secrets_for_screen_internal(create_screen_handles(special_warp_return_scr), from_active_screen, false, -1, do_replay_comment);
6627 204 }
6628
2/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✗ Branch 3 not taken.
536 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6629 {
6630 for (int layer = 0; layer <= 6; layer++)
6631 {
6632 mapscr* tscr = &special_warp_return_scrs[layer];
6633 for (int pos = 0; pos < 176; pos++)
6634 {
6635 newcombo const* cmb = &combobuf[tscr->data[pos]];
6636 if(cmb->type == cLIGHTTARGET)
6637 {
6638 if(!(cmb->usrflags&cflag1)) //Unlit version
6639 {
6640 tscr->data[pos] += 1;
6641 }
6642 }
6643 }
6644 }
6645 }
6646 536 }
6647
6648 screen_handles_t screen_handles;
6649
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 6349 times.
7256 for (int i = 0; i <= 6; i++)
6650
3/4
✓ Branch 0 taken 6349 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1284 times.
✓ Branch 3 taken 5065 times.
6349 screen_handles[i] = {scr, special_warp_return_scrs[i].is_valid() ? &special_warp_return_scrs[i] : nullptr, screen, i};
6651
6652
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 907 times.
✗ Branch 3 not taken.
907 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6653
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 toggle_gswitches_load(screen_handles);
6654
6655
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 902 times.
907 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6656 {
6657
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 remove_lockblocks(screen_handles);
6658 5 }
6659
6660
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 906 times.
907 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6661 {
6662
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6663 1 }
6664
6665
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mCHEST) // if special stuff done before
6666 {
6667 remove_chests(screen_handles);
6668 }
6669
6670
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6671 {
6672 remove_lockedchests(screen_handles);
6673 }
6674
6675
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6676 {
6677 remove_bosschests(screen_handles);
6678 }
6679
6680
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xdoors(screen_handles, true);
6681
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xstatecombos(screen_handles, true);
6682
6683 // check doors
6684
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if (isdungeon(destdmap, screen))
6685 {
6686
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 371 times.
1855 for(int32_t i=0; i<4; i++)
6687 {
6688 1484 int32_t door=scr->door[i];
6689
6690
4/5
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 89 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1295 times.
1484 switch(door)
6691 {
6692 case d1WAYSHUTTER:
6693 case dSHUTTER:
6694 if ((ldir^1)==i && screen == home_screen)
6695 {
6696 scr->door[i]=dOPENSHUTTER;
6697 }
6698
6699 get_screen_state(screen).open_doors = -4;
6700 105 break;
6701
6702 case dLOCKED:
6703
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 80 times.
91 if(game->maps[mi]&(mDOOR_UP<<i))
6704 {
6705 80 scr->door[i]=dUNLOCKED;
6706 80 }
6707
6708 91 break;
6709
6710 case dBOSS:
6711
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 5 times.
9 if(game->maps[mi]&(mDOOR_UP<<i))
6712 {
6713 5 scr->door[i]=dOPENBOSS;
6714 5 }
6715
6716 9 break;
6717
6718 case dBOMB:
6719
3/4
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 51 times.
89 if(game->maps[mi]&(mDOOR_UP<<i))
6720 {
6721 51 scr->door[i]=dBOMBED;
6722 51 }
6723
6724 89 break;
6725 }
6726
6727
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 105 times.
1589 update_door(scr, i, scr->door[i]);
6728
6729
4/4
✓ Branch 0 taken 1390 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1379 times.
1484 if(door==dSHUTTER||door==d1WAYSHUTTER)
6730 {
6731 105 scr->door[i]=door;
6732 105 }
6733 1484 }
6734 371 }
6735
6736
2/2
✓ Branch 0 taken 6139 times.
✓ Branch 1 taken 1117 times.
7256 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6737 {
6738
4/4
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 697 times.
✓ Branch 2 taken 593 times.
✓ Branch 3 taken 4849 times.
6139 if (j<0 || scr->layermap[j] > 0)
6739 {
6740
4/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 907 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 1 times.
1290 mapscr *layerscreen= (j<0 ? scr : special_warp_return_scrs[j+1].valid ? &special_warp_return_scrs[j+1] :
6741 1 &TheMaps[(scr->layermap[j]-1)*MAPSCRS]+scr->layerscreen[j]);
6742
6743
2/2
✓ Branch 0 taken 226830 times.
✓ Branch 1 taken 1500 times.
228330 for(int32_t i=0; i<176; ++i)
6744 {
6745 226830 int32_t c=layerscreen->data[i];
6746
6747 // New screen flag: Cycle Combos At Screen Init
6748
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 226824 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 210 times.
✓ Branch 7 taken 210 times.
226830 if(combobuf[c].nextcombo != 0 && (scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6749 {
6750 210 int32_t r = 0;
6751
6752
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 210 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
210 while(combobuf[c].can_cycle() && r++ < 10)
6753 {
6754 newcombo const& cmb = combobuf[c];
6755 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6756 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6757 layerscreen->data[i] = cid;
6758 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6759 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6760 c = layerscreen->data[i];
6761 }
6762 }
6763 227040 }
6764 1500 }
6765 6349 }
6766 1537 }
6767
6768 // Load screen (and layers). Unlike loadscr, this doesn't load to the global temporary_screens, but
6769 // instead returns an array of mapscr.
6770 // Used to draw/save the map.
6771 47360 std::array<mapscr, 7> loadscr2(int32_t screen)
6772 {
6773 47360 std::array<mapscr, 7> scrs;
6774 47360 mapscr* scr = &scrs[0];
6775
6776
2/2
✓ Branch 0 taken 66834661 times.
✓ Branch 1 taken 47360 times.
66882021 for(word x=0; x<animated_combos; x++)
6777 {
6778
2/2
✓ Branch 0 taken 33899045 times.
✓ Branch 1 taken 32935616 times.
66834661 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6779 {
6780 32935616 combobuf[animated_combo_table4[x][0]].aclk=0;
6781 32935616 }
6782 66834661 }
6783
6784
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 const mapscr* source = get_canonical_scr(cur_map, screen);
6785
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if (!source->is_valid())
6786 {
6787 scrs[0].valid = 0;
6788 return scrs;
6789 }
6790
6791
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 *scr = *get_canonical_scr(cur_map, screen);
6792
2/2
✓ Branch 0 taken 284160 times.
✓ Branch 1 taken 47360 times.
331520 for (int i = 1; i <= 6; i++)
6793 {
6794
2/2
✓ Branch 0 taken 209501 times.
✓ Branch 1 taken 74659 times.
284160 if (scr->layermap[i-1] > 0)
6795
2/4
✓ Branch 0 taken 74659 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 74659 times.
✗ Branch 3 not taken.
74659 scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6796 else
6797
2/4
✓ Branch 0 taken 209501 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 209501 times.
✗ Branch 3 not taken.
209501 scrs[i] = {};
6798 284160 }
6799
6800 screen_handles_t screen_handles;
6801
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 331520 times.
378880 for (int i = 0; i < 7; i++)
6802
3/4
✓ Branch 0 taken 331520 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114582 times.
✓ Branch 3 taken 216938 times.
331520 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
6803
6804 47360 int mi = mapind(cur_map, screen);
6805
6806
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47306 times.
✓ Branch 3 taken 54 times.
47360 if(canPermSecret(-1,screen))
6807 {
6808
3/4
✓ Branch 0 taken 47306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6344 times.
✓ Branch 3 taken 40962 times.
47306 if(game->maps[mi]&mSECRET) // if special stuff done before
6809 {
6810
1/2
✓ Branch 0 taken 6344 times.
✗ Branch 1 not taken.
6344 reveal_hidden_stairs(scr, screen, false);
6811 6344 bool from_active_screen = false;
6812 6344 bool do_replay_comment = true;
6813
1/2
✓ Branch 0 taken 6344 times.
✗ Branch 1 not taken.
6344 trigger_secrets_for_screen_internal(screen_handles, from_active_screen, false, -1, do_replay_comment);
6814 6344 }
6815
3/4
✓ Branch 0 taken 47306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47289 times.
✓ Branch 3 taken 17 times.
47306 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6816 {
6817
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 17 times.
136 for (int layer = 0; layer <= 6; layer++)
6818 {
6819 119 mapscr* tscr = &scrs[layer];
6820
2/2
✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 119 times.
21063 for (int pos = 0; pos < 176; pos++)
6821 {
6822 20944 newcombo const* cmb = &combobuf[tscr->data[pos]];
6823
2/2
✓ Branch 0 taken 20927 times.
✓ Branch 1 taken 17 times.
20944 if(cmb->type == cLIGHTTARGET)
6824 {
6825
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!(cmb->usrflags&cflag1)) //Unlit version
6826 {
6827 17 tscr->data[pos] += 1;
6828 17 }
6829 17 }
6830 20944 }
6831 119 }
6832 17 }
6833 47306 }
6834
6835
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 271 times.
✓ Branch 3 taken 47089 times.
47360 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6836 {
6837
1/2
✓ Branch 0 taken 271 times.
✗ Branch 1 not taken.
271 remove_lockblocks(screen_handles);
6838 271 }
6839
6840
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 47359 times.
47360 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6841 {
6842
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6843 1 }
6844
6845
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 106 times.
✓ Branch 3 taken 47254 times.
47360 if(game->maps[mi]&mCHEST) // if special stuff done before
6846 {
6847
1/2
✓ Branch 0 taken 106 times.
✗ Branch 1 not taken.
106 remove_chests(screen_handles);
6848 106 }
6849
6850
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 47336 times.
47360 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6851 {
6852
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 remove_lockedchests(screen_handles);
6853 24 }
6854
6855
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 47360 times.
47360 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6856 {
6857 remove_bosschests(screen_handles);
6858 }
6859
6860
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 clear_xdoors(screen_handles);
6861
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 clear_xstatecombos(screen_handles);
6862
6863 // check doors
6864
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47306 times.
✓ Branch 3 taken 54 times.
47360 if (isdungeon(screen))
6865 {
6866
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 54 times.
270 for(int32_t i=0; i<4; i++)
6867 {
6868 216 int32_t door=scr->door[i];
6869 216 bool putit=true;
6870
6871
4/5
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 139 times.
216 switch(door)
6872 {
6873 case d1WAYSHUTTER:
6874 case dSHUTTER:
6875 61 break;
6876
6877 case dLOCKED:
6878
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(game->maps[mi]&(mDOOR_UP<<i))
6879 {
6880 12 scr->door[i]=dUNLOCKED;
6881 12 }
6882
6883 12 break;
6884
6885 case dBOSS:
6886
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(game->maps[mi]&(mDOOR_UP<<i))
6887 {
6888 scr->door[i]=dOPENBOSS;
6889 }
6890
6891 4 break;
6892
6893 case dBOMB:
6894 if(game->maps[mi]&(mDOOR_UP<<i))
6895 {
6896 scr->door[i]=dBOMBED;
6897 }
6898
6899 break;
6900 }
6901
6902
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(putit)
6903 {
6904
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 putdoor(scr, scrollbuf, i, scr->door[i], false);
6905 216 }
6906
6907
3/4
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
216 if(door==dSHUTTER||door==d1WAYSHUTTER)
6908 {
6909 61 scr->door[i]=door;
6910 61 }
6911 216 }
6912 54 }
6913
6914
2/2
✓ Branch 0 taken 331520 times.
✓ Branch 1 taken 47360 times.
378880 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6915 {
6916
4/4
✓ Branch 0 taken 284160 times.
✓ Branch 1 taken 47360 times.
✓ Branch 2 taken 74659 times.
✓ Branch 3 taken 209501 times.
331520 if (j < 0 || scr->layermap[j] > 0)
6917 {
6918
2/2
✓ Branch 0 taken 74659 times.
✓ Branch 1 taken 47360 times.
122019 mapscr *layerscreen= (j<0 ? scr
6919 74659 : &(TheMaps[(scr->layermap[j]-1)*MAPSCRS+scr->layerscreen[j]]));
6920
6921
2/2
✓ Branch 0 taken 21475344 times.
✓ Branch 1 taken 122019 times.
21597363 for(int32_t i=0; i<176; ++i)
6922 {
6923 21475344 int32_t c=layerscreen->data[i];
6924
6925 // New screen flag: Cycle Combos At Screen Init
6926
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 21475344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
21475344 if((scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6927 {
6928 int32_t r = 0;
6929
6930 while(combobuf[c].can_cycle() && r++ < 10)
6931 {
6932 newcombo const& cmb = combobuf[c];
6933 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6934 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6935 layerscreen->data[i] = cid;
6936 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6937 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6938 c = layerscreen->data[i];
6939 }
6940 }
6941 21475344 }
6942 122019 }
6943 331520 }
6944
6945 47360 return scrs;
6946
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 }
6947
6948 19761169 void putscr(mapscr* scr, BITMAP* dest, int32_t x, int32_t y)
6949 {
6950 // This is a bogus value while screenscrolling == true, but that's ok
6951 // because it is only used to calculate the rpos, and during screenscrolling
6952 // only the modulus to get pos (draw_cmb_pos does RPOS_TO_POS) is needed, which
6953 // is always the same no matter the value of scr.
6954 19761169 int screen = get_screen_for_world_xy(x, y);
6955
6956 19761169 x -= viewport.x;
6957 19761169 y -= viewport.y;
6958
6959
3/6
✓ Branch 0 taken 19761169 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19761169 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19761169 times.
19761169 if (!scr->is_valid()||!show_layers[0]||scr->hidelayers & 1)
6960 {
6961 rectfill(dest,x,y,x+255,y+175,0);
6962 return;
6963 }
6964
6965 39374871 bool over = XOR(scr->flags7&fLAYER2BG,DMaps[cur_dmap].flags&dmfLAYER2BG)
6966
2/2
✓ Branch 0 taken 19613702 times.
✓ Branch 1 taken 147467 times.
19761169 || XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
6967
2/2
✓ Branch 0 taken 243651 times.
✓ Branch 1 taken 19370051 times.
19613702 || !get_qr(qr_CLASSIC_DRAWING_ORDER);
6968
6969 int start_x, end_x, start_y, end_y;
6970 19761169 get_bounds_for_draw_cmb_calls(dest, x, y, start_x, end_x, start_y, end_y);
6971
2/2
✓ Branch 0 taken 19761169 times.
✓ Branch 1 taken 210471533 times.
230232702 for (int cy = start_y; cy < end_y; cy++)
6972 {
6973
2/2
✓ Branch 0 taken 3195542754 times.
✓ Branch 1 taken 210471533 times.
3406014287 for (int cx = start_x; cx < end_x; cx++)
6974 {
6975 3195542754 int i = cx + cy*16;
6976
2/2
✓ Branch 0 taken 374288294 times.
✓ Branch 1 taken 2821254460 times.
3195542754 auto rpos = screenscrolling ? rpos_t::None : POS_TO_RPOS(i, screen);
6977 3195542754 draw_cmb_pos(dest, x + cx*16, y + cy*16, rpos, scr->data[i], scr->cset[i], 0, over, false);
6978 3195542754 }
6979 210471533 }
6980 19761169 }
6981
6982 16127266 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y)
6983 {
6984
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16127266 times.
16127266 if (!show_layers[0])
6985 {
6986 return;
6987 }
6988
6989 16127266 x -= viewport.x;
6990 16127266 y -= viewport.y;
6991
6992
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16127266 times.
32390850 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
6993 16263584 mapscr* scr = screen_handles[0].base_scr;
6994
1/2
✓ Branch 0 taken 16263584 times.
✗ Branch 1 not taken.
16263584 if (!scr->is_valid())
6995 return;
6996
6997
2/2
✓ Branch 0 taken 123411 times.
✓ Branch 1 taken 16140173 times.
16263584 if(scr->door[0]==dBOMBED)
6998 {
6999 123411 over_door(scr, dest, 39, up, offx+x, offy+y);
7000 123411 }
7001
7002
2/2
✓ Branch 0 taken 143109 times.
✓ Branch 1 taken 16120475 times.
16263584 if(scr->door[1]==dBOMBED)
7003 {
7004 143109 over_door(scr, dest, 135, down, offx+x, offy+y);
7005 143109 }
7006
7007
2/2
✓ Branch 0 taken 155862 times.
✓ Branch 1 taken 16107722 times.
16263584 if(scr->door[2]==dBOMBED)
7008 {
7009 155862 over_door(scr, dest, 66, left, offx+x, offy+y);
7010 155862 }
7011
7012
2/2
✓ Branch 0 taken 132289 times.
✓ Branch 1 taken 16131295 times.
16263584 if(scr->door[3]==dBOMBED)
7013 {
7014 132289 over_door(scr, dest, 77, right, offx+x, offy+y);
7015 132289 }
7016 16263584 });
7017 16127266 }
7018
7019 3497585 void putscrdoors(mapscr* scr, BITMAP *dest, int32_t x, int32_t y)
7020 {
7021
2/4
✓ Branch 0 taken 3497585 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3497585 times.
✗ Branch 3 not taken.
3497585 if (!scr->is_valid() || !show_layers[0])
7022 return;
7023
7024 3497585 x -= viewport.x;
7025 3497585 y -= viewport.y;
7026
7027
2/2
✓ Branch 0 taken 37656 times.
✓ Branch 1 taken 3459929 times.
3497585 if(scr->door[0]==dBOMBED)
7028 {
7029 37656 over_door(scr,dest,39,up,x,y);
7030 37656 }
7031
7032
2/2
✓ Branch 0 taken 36495 times.
✓ Branch 1 taken 3461090 times.
3497585 if(scr->door[1]==dBOMBED)
7033 {
7034 36495 over_door(scr,dest,135,down,x,y);
7035 36495 }
7036
7037
2/2
✓ Branch 0 taken 40440 times.
✓ Branch 1 taken 3457145 times.
3497585 if(scr->door[2]==dBOMBED)
7038 {
7039 40440 over_door(scr,dest,66,left,x,y);
7040 40440 }
7041
7042
2/2
✓ Branch 0 taken 37063 times.
✓ Branch 1 taken 3460522 times.
3497585 if(scr->door[3]==dBOMBED)
7043 {
7044 37063 over_door(scr,dest,77,right,x,y);
7045 37063 }
7046 3497585 }
7047 262948537 static inline bool standing_on_z(newcombo const& cmb, zfix const& standing_z_state)
7048 {
7049
1/2
✓ Branch 0 taken 262948537 times.
✗ Branch 1 not taken.
262948537 if (cmb.dive_under_level)
7050 {
7051 if (standing_z_state <= -cmb.dive_under_level)
7052 return true;
7053 }
7054
7055 262948537 zfix cmb_z, cmb_z_step;
7056
4/4
✓ Branch 0 taken 92789 times.
✓ Branch 1 taken 262855748 times.
✓ Branch 2 taken 88819 times.
✓ Branch 3 taken 3970 times.
262948537 if(cmb.type == cCSWITCHBLOCK && (cmb.usrflags & cflag9))
7057 {
7058 3970 cmb_z = zslongToFix(cmb.attributes[2]);
7059
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3970 times.
3970 cmb_z_step = zslongToFix(zc_max(0,cmb.attributes[3]));
7060 3970 }
7061
2/2
✓ Branch 0 taken 1983 times.
✓ Branch 1 taken 262942584 times.
262944567 else if(cmb.genflags & cflag3)
7062 {
7063 1983 cmb_z = cmb.z_height;
7064
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1983 times.
1983 cmb_z_step = zc_max(0_zf,cmb.z_step_height);
7065 1983 }
7066 262942584 else return false;
7067
7068
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5953 times.
5953 if (standing_z_state == STANDING_Z_MAX) // 'infinity'
7069 return true;
7070
2/2
✓ Branch 0 taken 1149 times.
✓ Branch 1 taken 4804 times.
5953 if (!cmb_z) return false; // infinite height
7071
7072 4804 return (cmb_z - cmb_z_step) <= standing_z_state;
7073 262948537 }
7074 62148814 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt)
7075 {
7076 62148814 return _walkflag(zx,zy,cnt,0_zf);
7077 }
7078
7079 142608273 bool _walkflag_new(const mapscr* s0, const mapscr* s1, const mapscr* s2, zfix_round zx, zfix_round zy, zfix const& standing_z_state, bool is_temp_screens)
7080 {
7081 142608273 int x = zx.getRound(), y = zy.getRound();
7082 142608273 int pos = COMBOPOS(x % 256, y % 176);
7083 142608273 const newcombo& c = combobuf[s0->data[pos]];
7084 142608273 const newcombo& c1 = combobuf[s1->data[pos]];
7085 142608273 const newcombo& c2 = combobuf[s2->data[pos]];
7086
4/4
✓ Branch 0 taken 140516647 times.
✓ Branch 1 taken 2091626 times.
✓ Branch 2 taken 140507187 times.
✓ Branch 3 taken 9460 times.
285446536 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
7087
4/4
✓ Branch 0 taken 114995 times.
✓ Branch 1 taken 140622182 times.
✓ Branch 2 taken 2211836 times.
✓ Branch 3 taken 4245 times.
142608273 (iswater_type(c2.type))) && DRIEDLAKE);
7088 142838263 int32_t b=1;
7089
2/2
✓ Branch 0 taken 70422690 times.
✓ Branch 1 taken 72415573 times.
142838263 if(x&8) b<<=2;
7090
2/2
✓ Branch 0 taken 66766599 times.
✓ Branch 1 taken 76071664 times.
142838263 if(y&8) b<<=1;
7091
7092 142838263 int32_t cwalkflag = c.walk;
7093
4/4
✓ Branch 0 taken 142723259 times.
✓ Branch 1 taken 115004 times.
✓ Branch 2 taken 142723095 times.
✓ Branch 3 taken 164 times.
142838263 if(is_temp_screens && standing_on_z(c,standing_z_state)) cwalkflag &= (c.walk>>4)^0xF;
7094
8/10
✓ Branch 0 taken 57502 times.
✓ Branch 1 taken 142780597 times.
✓ Branch 2 taken 2206612 times.
✓ Branch 3 taken 2149110 times.
✓ Branch 4 taken 2206612 times.
✓ Branch 5 taken 142723095 times.
✓ Branch 6 taken 2206612 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2206612 times.
✗ Branch 9 not taken.
142838099 else if ((c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) || (iswater_type(c.type) && ((c.walk>>4)&b) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
7095
2/2
✓ Branch 0 taken 63206882 times.
✓ Branch 1 taken 79516377 times.
142723259 if (s1 != s0)
7096 {
7097
3/4
✓ Branch 0 taken 79516377 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 79515759 times.
✓ Branch 3 taken 618 times.
79516377 if(is_temp_screens && standing_on_z(c1,standing_z_state)) cwalkflag &= (c1.walk>>4)^0xF;
7098
4/10
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 79504030 times.
✓ Branch 2 taken 11729 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11729 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
79515759 else if ((iswater_type(c1.type) && ((c1.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_1) && !((c1.usrflags&cflag3) || (c1.usrflags&cflag4)))) cwalkflag &= c1.walk;
7099
2/2
✓ Branch 0 taken 71255 times.
✓ Branch 1 taken 79444504 times.
79515759 else if (c1.type == cBRIDGE)
7100 {
7101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71255 times.
71255 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
7102 {
7103 71255 int efflag = (c1.walk & 0xF0)>>4;
7104 71255 int newsolid = (c1.walk & 0xF);
7105 71255 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
7106 71255 }
7107 else cwalkflag &= c1.walk;
7108 71255 }
7109
3/8
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 79432775 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11729 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
79444504 else if ((iswater_type(c1.type) && get_qr(qr_WATER_ON_LAYER_1) && ((c1.usrflags&cflag3) || (c1.usrflags&cflag4)) && ((c1.walk>>4)&b))) cwalkflag = 0;
7110 79444504 else cwalkflag |= c1.walk;
7111 79516377 }
7112
2/2
✓ Branch 0 taken 102014358 times.
✓ Branch 1 taken 40708901 times.
142723259 if (s2 != s0)
7113 {
7114
2/4
✓ Branch 0 taken 40708901 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40708901 times.
✗ Branch 3 not taken.
40708901 if(is_temp_screens && standing_on_z(c2,standing_z_state)) cwalkflag &= (c2.walk>>4)^0xF;
7115
7/10
✓ Branch 0 taken 5889 times.
✓ Branch 1 taken 40703012 times.
✓ Branch 2 taken 5889 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3735 times.
✓ Branch 5 taken 2154 times.
✓ Branch 6 taken 3735 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 3735 times.
40708901 else if ((iswater_type(c2.type) && ((c2.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_2) && !((c2.usrflags&cflag3) || (c2.usrflags&cflag4)))) cwalkflag &= c2.walk;
7116
2/2
✓ Branch 0 taken 16725 times.
✓ Branch 1 taken 40688441 times.
40705166 else if (c2.type == cBRIDGE)
7117 {
7118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16725 times.
16725 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
7119 {
7120 16725 int efflag = (c2.walk & 0xF0)>>4;
7121 16725 int newsolid = (c2.walk & 0xF);
7122 16725 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
7123 16725 }
7124 else cwalkflag &= c2.walk;
7125 16725 }
7126
3/8
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 40686287 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2154 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
40688441 else if ((iswater_type(c2.type) && get_qr(qr_WATER_ON_LAYER_2) && ((c2.usrflags&cflag3) || (c2.usrflags&cflag4))) && ((c2.walk>>4)&b)) cwalkflag = 0;
7127 40688441 else cwalkflag |= c2.walk;
7128 40708901 }
7129
7130
4/4
✓ Branch 0 taken 30807555 times.
✓ Branch 1 taken 111915704 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 30806607 times.
142723259 if((cwalkflag&b) && !dried)
7131 30806607 return true;
7132
7133
3/4
✓ Branch 0 taken 111916652 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 111847462 times.
✓ Branch 3 taken 69190 times.
111916652 if (is_temp_screens && collide_object(zx, zy, 0.0001_zf, 0.0001_zf)) return true;
7134
7135 111847462 return false;
7136 142723259 }
7137
7138 // Returns true if the combo at viewport position x,y is solid. Looks at a combo's quadrant walkablity flags.
7139 142723259 static bool _walkflag_new(zfix_round zx, zfix_round zy, zfix const& standing_z_state)
7140 {
7141 142723259 int x = zx.getRound(), y = zy.getRound();
7142 142723259 mapscr* s0 = get_scr_for_world_xy_layer(x, y, 0);
7143 142723259 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
7144 142723259 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
7145
2/2
✓ Branch 0 taken 63206882 times.
✓ Branch 1 taken 79516377 times.
142723259 if (!s1->valid) s1 = s0;
7146
2/2
✓ Branch 0 taken 102014358 times.
✓ Branch 1 taken 40708901 times.
142723259 if (!s2->valid) s2 = s0;
7147 142723259 return _walkflag_new(s0, s1, s2, zx, zy, standing_z_state, true);
7148 }
7149
7150 138195586 bool _walkflag(zfix_round x,zfix_round y,int32_t cnt,zfix const& standing_z_state)
7151 {
7152 138195586 int max_x = world_w;
7153 138195586 int max_y = world_h;
7154
2/2
✓ Branch 0 taken 78152849 times.
✓ Branch 1 taken 60042737 times.
138195586 if (!get_qr(qr_LTTPWALK))
7155 {
7156 60042737 max_x -= 7;
7157 60042737 max_y -= 7;
7158 60042737 }
7159
4/4
✓ Branch 0 taken 137923218 times.
✓ Branch 1 taken 272368 times.
✓ Branch 2 taken 83268 times.
✓ Branch 3 taken 137839950 times.
138195586 if (x < 0 || y < 0) return false;
7160
2/2
✓ Branch 0 taken 323548 times.
✓ Branch 1 taken 137516402 times.
137839950 if (x >= max_x) return false;
7161
3/4
✓ Branch 0 taken 571808 times.
✓ Branch 1 taken 136944594 times.
✓ Branch 2 taken 571808 times.
✗ Branch 3 not taken.
137516402 if (x >= max_x - 8 && cnt == 2) return false;
7162
2/2
✓ Branch 0 taken 136962139 times.
✓ Branch 1 taken 554263 times.
137516402 if (y >= max_y) return false;
7163
7164
4/4
✓ Branch 0 taken 30757577 times.
✓ Branch 1 taken 106204562 times.
✓ Branch 2 taken 100443442 times.
✓ Branch 3 taken 5761120 times.
136962139 return _walkflag_new(x, y, standing_z_state) || (cnt != 1 && _walkflag_new(x + 8, y, standing_z_state));
7165 138195586 }
7166
7167 105110712 static bool effectflag(int32_t x, int32_t y, int32_t layer)
7168 {
7169 105110712 mapscr* s0 = get_scr_for_world_xy(x, y);
7170 105110712 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
7171 105110712 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
7172
2/2
✓ Branch 0 taken 57655235 times.
✓ Branch 1 taken 47455477 times.
105110712 if (!s1->valid) s1 = s0;
7173
2/2
✓ Branch 0 taken 24622036 times.
✓ Branch 1 taken 80488676 times.
105110712 if (!s2->valid) s2 = s0;
7174
7175 105110712 int pos = COMBOPOS(x % 256, y % 176);
7176 105110712 const newcombo& c = combobuf[s0->data[pos]];
7177 105110712 const newcombo& c1 = combobuf[s1->data[pos]];
7178 105110712 const newcombo& c2 = combobuf[s2->data[pos]];
7179
4/4
✓ Branch 0 taken 104115008 times.
✓ Branch 1 taken 995704 times.
✓ Branch 2 taken 104113728 times.
✓ Branch 3 taken 1280 times.
210221424 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
7180
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 104113728 times.
✓ Branch 2 taken 995300 times.
✓ Branch 3 taken 1684 times.
105110712 (iswater_type(c2.type))) && DRIEDLAKE);
7181 105110712 int32_t b=1;
7182
2/2
✓ Branch 0 taken 53191910 times.
✓ Branch 1 taken 51918802 times.
105110712 if(x&8) b<<=2;
7183
2/2
✓ Branch 0 taken 44691465 times.
✓ Branch 1 taken 60419247 times.
105110712 if(y&8) b<<=1;
7184
7185 105110712 int32_t cwalkflag = (c.walk>>4);
7186
2/2
✓ Branch 0 taken 80355195 times.
✓ Branch 1 taken 24755517 times.
105110712 if (layer == 0) cwalkflag = (c1.walk>>4);
7187
2/2
✓ Branch 0 taken 80356789 times.
✓ Branch 1 taken 24753923 times.
105110712 if (layer == 1) cwalkflag = (c2.walk>>4);
7188 //if (c.type == cBRIDGE || (iswater_type(c.type) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
7189
4/4
✓ Branch 0 taken 57655235 times.
✓ Branch 1 taken 47455477 times.
✓ Branch 2 taken 24571560 times.
✓ Branch 3 taken 33083675 times.
105110712 if (s1 != s0 && layer < 0)
7190 {
7191
2/2
✓ Branch 0 taken 24555346 times.
✓ Branch 1 taken 16214 times.
24571560 if (c1.type == cBRIDGE) cwalkflag &= (~(c1.walk>>4));
7192 24571560 }
7193
4/4
✓ Branch 0 taken 24622036 times.
✓ Branch 1 taken 80488676 times.
✓ Branch 2 taken 17773115 times.
✓ Branch 3 taken 6848921 times.
105110712 if (s2 != s0 && layer < 1)
7194 {
7195
2/2
✓ Branch 0 taken 17761231 times.
✓ Branch 1 taken 11884 times.
17773115 if (c2.type == cBRIDGE) cwalkflag &= (~(c2.walk>>4));
7196 17773115 }
7197
7198
2/2
✓ Branch 0 taken 104932708 times.
✓ Branch 1 taken 178004 times.
105110712 return (cwalkflag&b) ? !dried : false;
7199 }
7200
7201 105484036 bool _effectflag(int32_t x,int32_t y,int32_t cnt, int32_t layer, bool notLink)
7202 {
7203 DCHECK(cnt == 0 || cnt == 1);
7204 105484036 int max_x = world_w;
7205 105484036 int max_y = world_h;
7206
3/4
✓ Branch 0 taken 45833723 times.
✓ Branch 1 taken 59650313 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45833723 times.
105484036 if (!get_qr(qr_LTTPWALK) && !notLink)
7207 {
7208 45833723 max_x -= 7;
7209 45833723 max_y -= 7;
7210 45833723 }
7211
4/4
✓ Branch 0 taken 105483284 times.
✓ Branch 1 taken 752 times.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 105483080 times.
105484036 if (x < 0 || y < 0) return false;
7212
2/2
✓ Branch 0 taken 816 times.
✓ Branch 1 taken 105482264 times.
105483080 if (x >= max_x) return false;
7213
3/4
✓ Branch 0 taken 526426 times.
✓ Branch 1 taken 104955838 times.
✓ Branch 2 taken 526426 times.
✗ Branch 3 not taken.
105482264 if (x >= max_x - 8 && cnt == 2) return false;
7214
2/2
✓ Branch 0 taken 371552 times.
✓ Branch 1 taken 105110712 times.
105482264 if (y >= max_y) return false;
7215
7216
3/4
✓ Branch 0 taken 104931918 times.
✓ Branch 1 taken 178794 times.
✓ Branch 2 taken 178794 times.
✗ Branch 3 not taken.
105110712 return effectflag(x, y, layer) || (cnt == 2 && effectflag(x + 8, y, layer));
7217 105484036 }
7218
7219 // used by mapdata->isSolid(x,y) in ZScript
7220 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7221 {
7222 int x = zx.getRound(), y = zy.getRound();
7223 {
7224 int max_x = 256;
7225 int max_y = 176;
7226 if (!get_qr(qr_LTTPWALK))
7227 {
7228 max_x -= 7;
7229 max_y -= 7;
7230 }
7231 if (x < 0 || y < 0) return false;
7232 if (x >= max_x) return false;
7233 if (x >= max_x - 8 && cnt == 2) return false;
7234 if (y >= max_y) return false;
7235 }
7236
7237 const mapscr *s1, *s2;
7238 s1 = s2 = m;
7239
7240 if ( m->layermap[0] > 0 && m->layermap[0] <= map_count )
7241 {
7242 const mapscr* s = get_canonical_scr(m->layermap[0] - 1, m->layerscreen[0]);
7243 if (s->is_valid())
7244 s1 = s;
7245 }
7246
7247 if ( m->layermap[1] > 0 && m->layermap[1] <= map_count )
7248 {
7249 const mapscr* s = get_canonical_scr(m->layermap[1] - 1, m->layerscreen[1]);
7250 if (s->is_valid())
7251 s2 = s;
7252 }
7253
7254 zfix unused;
7255 return _walkflag_new(m, s1, s2, x, y, unused, false) || (cnt != 1 && _walkflag_new(m, s1, s2, x + 8, y, unused, false));
7256 }
7257
7258 bool _walkflag_layer(zfix_round x, zfix_round y, int32_t layer, int32_t cnt)
7259 {
7260 DCHECK_LAYER_NEG1_INDEX(layer);
7261 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7262 if (!m->is_valid()) return false;
7263 return _walkflag_layer(x, y, cnt, m);
7264 }
7265
7266 static bool _walkflag_layer_new(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m, int max_x, int max_y)
7267 {
7268 int x = zx.getRound(), y = zy.getRound();
7269
7270 if (!get_qr(qr_LTTPWALK))
7271 {
7272 max_x -= 7;
7273 max_y -= 7;
7274 }
7275 if (x < 0 || y < 0) return false;
7276 if (x >= max_x) return false;
7277 if (x >= max_x - 8 && cnt == 2) return false;
7278 if (y >= max_y) return false;
7279
7280 if(!m) return true;
7281
7282 int pos = COMBOPOS(x%256, y%176);
7283 const newcombo* c = &combobuf[m->data[pos]];
7284 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7285 int32_t b=1;
7286
7287 if(x&8) b<<=2;
7288
7289 if(y&8) b<<=1;
7290
7291 if((c->walk&b) && !dried)
7292 return true;
7293
7294 if(cnt==1) return false;
7295
7296 ++pos;
7297
7298 if(!(x&8))
7299 b<<=2;
7300 else
7301 {
7302 c = &combobuf[m->data[pos]];
7303 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7304 b=1;
7305
7306 if(y&8) b<<=1;
7307 }
7308
7309 return (c->walk&b) ? !dried : false;
7310 }
7311
7312 //Only check the given mapscr*, not its layer 1&2
7313 bool _walkflag_layer(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7314 {
7315 return _walkflag_layer_new(zx, zy, cnt, m, world_w, world_h);
7316 }
7317
7318 bool _walkflag_layer_scrolling(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7319 {
7320 return _walkflag_layer_new(zx, zy, cnt, m, scrolling_region.width, scrolling_region.height);
7321 }
7322
7323 447898 bool _effectflag_layer(int32_t x, int32_t y, int32_t layer, int32_t cnt, bool notLink)
7324 {
7325 DCHECK_LAYER_NEG1_INDEX(layer);
7326 447898 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7327
2/2
✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 446136 times.
447898 if (!m->is_valid()) return false;
7328 446136 return _effectflag_layer(x, y, cnt, m, notLink);
7329 447898 }
7330
7331 519213 bool _effectflag_layer(int32_t x,int32_t y,int32_t cnt, mapscr* m, bool notLink)
7332 {
7333 519213 int max_x = world_w;
7334 519213 int max_y = world_h;
7335
3/4
✓ Branch 0 taken 50002 times.
✓ Branch 1 taken 469211 times.
✓ Branch 2 taken 50002 times.
✗ Branch 3 not taken.
519213 if (!get_qr(qr_LTTPWALK) && !notLink)
7336 {
7337 max_x -= 7;
7338 max_y -= 7;
7339 }
7340
2/4
✓ Branch 0 taken 519213 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 519213 times.
519213 if (x < 0 || y < 0) return false;
7341
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 519213 times.
519213 if (x >= max_x) return false;
7342
3/4
✓ Branch 0 taken 1342 times.
✓ Branch 1 taken 517871 times.
✓ Branch 2 taken 1342 times.
✗ Branch 3 not taken.
519213 if (x >= max_x - 8 && cnt == 2) return false;
7343
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 519213 times.
519213 if (y >= max_y) return false;
7344
7345
1/2
✓ Branch 0 taken 519213 times.
✗ Branch 1 not taken.
519213 if (!m) return true;
7346
7347 519213 int pos = COMBOPOS(x%256, y%176);
7348 519213 const newcombo* c = &combobuf[m->data[pos]];
7349
3/4
✓ Branch 0 taken 518813 times.
✓ Branch 1 taken 400 times.
✓ Branch 2 taken 400 times.
✗ Branch 3 not taken.
519613 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7350 519213 int32_t b=1;
7351
7352
2/2
✓ Branch 0 taken 276528 times.
✓ Branch 1 taken 242685 times.
519213 if(x&8) b<<=2;
7353
7354
2/2
✓ Branch 0 taken 220331 times.
✓ Branch 1 taken 298882 times.
519213 if(y&8) b<<=1;
7355
7356
3/4
✓ Branch 0 taken 450224 times.
✓ Branch 1 taken 68989 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 450224 times.
519213 if(((c->walk>>4)&b) && !dried)
7357 450224 return true;
7358
7359
1/2
✓ Branch 0 taken 68989 times.
✗ Branch 1 not taken.
68989 if(cnt==1) return false;
7360
7361 ++pos;
7362
7363 if(!(x&8))
7364 b<<=2;
7365 else
7366 {
7367 c = &combobuf[m->data[pos]];
7368 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7369 b=1;
7370
7371 if(y&8) b<<=1;
7372 }
7373
7374 return ((c->walk>>4)&b) ? !dried : false;
7375 519213 }
7376
7377 860420 bool water_walkflag(int32_t x, int32_t y, int32_t cnt)
7378 {
7379 860420 int max_x = world_w;
7380 860420 int max_y = world_h;
7381
2/2
✓ Branch 0 taken 165182 times.
✓ Branch 1 taken 695238 times.
860420 if (!get_qr(qr_LTTPWALK))
7382 {
7383 695238 max_x -= 7;
7384 695238 max_y -= 7;
7385 695238 }
7386
2/4
✓ Branch 0 taken 860420 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 860420 times.
860420 if (x < 0 || y < 0) return false;
7387
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if (x >= max_x) return false;
7388
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
860420 if (x >= max_x - 8 && cnt == 2) return false;
7389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if (y >= max_y) return false;
7390
7391
3/4
✓ Branch 0 taken 17860 times.
✓ Branch 1 taken 842560 times.
✓ Branch 2 taken 842560 times.
✗ Branch 3 not taken.
860420 return water_walkflag(x, y) || (cnt != 1 && water_walkflag(x + 8, y));
7392 860420 }
7393
7394 860420 bool water_walkflag(int32_t x, int32_t y)
7395 {
7396 860420 const newcombo& c = combobuf[MAPCOMBO2(-1, x, y)];
7397 860420 const newcombo& c1 = combobuf[MAPCOMBO2(0, x, y)];
7398 860420 const newcombo& c2 = combobuf[MAPCOMBO2(1, x, y)];
7399
7400 860420 int32_t b=1;
7401
2/2
✓ Branch 0 taken 439102 times.
✓ Branch 1 taken 421318 times.
860420 if(x&8) b<<=2;
7402
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if(y&8) b<<=1;
7403
7404
2/2
✓ Branch 0 taken 74192 times.
✓ Branch 1 taken 786228 times.
860420 if(get_qr(qr_NO_SOLID_SWIM))
7405 {
7406
2/2
✓ Branch 0 taken 474 times.
✓ Branch 1 taken 73718 times.
74192 if(c.walk&b)
7407 474 return true;
7408
7409
2/2
✓ Branch 0 taken 914 times.
✓ Branch 1 taken 72804 times.
73718 if(c1.walk&b)
7410 914 return true;
7411
7412
2/2
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 72733 times.
72804 if(c2.walk&b)
7413 71 return true;
7414 72733 }
7415 else
7416 {
7417
4/4
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 750095 times.
✓ Branch 2 taken 19762 times.
✓ Branch 3 taken 16371 times.
786228 if((c.walk&b) && !iswater_type(c.type))
7418 16371 return true;
7419
7420
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 769840 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
769857 if((c1.walk&b) && !iswater_type(c1.type))
7421 17 return true;
7422
7423
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 769827 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
769840 if((c2.walk&b) && !iswater_type(c2.type))
7424 13 return true;
7425 }
7426
7427 842560 return false;
7428 860420 }
7429
7430 589885 bool hit_walkflag(int32_t x,int32_t y,int32_t cnt)
7431 {
7432
2/2
✓ Branch 0 taken 100391 times.
✓ Branch 1 taken 489494 times.
589885 if(dlevel)
7433
8/8
✓ Branch 0 taken 488049 times.
✓ Branch 1 taken 1445 times.
✓ Branch 2 taken 484722 times.
✓ Branch 3 taken 3327 times.
✓ Branch 4 taken 483005 times.
✓ Branch 5 taken 1717 times.
✓ Branch 6 taken 4386 times.
✓ Branch 7 taken 478619 times.
489494 if(x<32 || y<40 || (x+(cnt-1)*8)>=world_w-32 || y>=world_h-32)
7434 10875 return true;
7435
7436
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 579008 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
579010 if(blockpath && y<((get_qr(qr_LTTPCOLLISION))?80:88))
7437 return true;
7438
7439
8/8
✓ Branch 0 taken 578724 times.
✓ Branch 1 taken 286 times.
✓ Branch 2 taken 578481 times.
✓ Branch 3 taken 243 times.
✓ Branch 4 taken 578270 times.
✓ Branch 5 taken 211 times.
✓ Branch 6 taken 396 times.
✓ Branch 7 taken 577874 times.
579010 if(x<16 || y<16 || (x+(cnt-1)*8)>=world_w-16 || y>=world_h-16)
7440 1136 return true;
7441
7442 // for(int32_t i=0; i<4; i++)
7443
4/4
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 577033 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 805 times.
577874 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7444 36 return true;
7445
7446
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 577837 times.
577838 if (collide_object(x, y,cnt*8, 1))
7447 1 return true;
7448
7449 577837 return _walkflag(x,y,cnt);
7450 589885 }
7451
7452 12220 bool solpush_walkflag(int32_t x, int32_t y, int32_t cnt, solid_object const* ign)
7453 {
7454 // 16 pixel buffer to account for slopes that are on bordering screens.
7455
4/8
✓ Branch 0 taken 12220 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12220 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12220 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12220 times.
12220 if(x<0 || y<0 || x>=world_w+16 || y>=world_h+16)
7456 return true;
7457
7458 // for(int32_t i=0; i<4; i++)
7459
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12220 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12220 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7460 return true;
7461
7462
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12220 times.
12220 if (collide_object(x, y,cnt*8, 1, ign))
7463 return true;
7464
7465 12220 return _walkflag(x,y,cnt);
7466 12220 }
7467
7468 39585 void map_bkgsfx(bool on)
7469 {
7470
2/2
✓ Branch 0 taken 39564 times.
✓ Branch 1 taken 21 times.
39585 if(on)
7471 {
7472 39564 cont_sfx(hero_scr->oceansfx);
7473
7474
4/4
✓ Branch 0 taken 369 times.
✓ Branch 1 taken 39195 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 54 times.
39564 if(hero_scr->bosssfx && !(game->lvlitems[dlevel]&(1 << li_boss_killed)))
7475 315 cont_sfx(hero_scr->bosssfx);
7476 39564 }
7477 else
7478 {
7479 21 adjust_sfx(hero_scr->oceansfx,128,false);
7480 21 adjust_sfx(hero_scr->bosssfx,128,false);
7481
7482
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 21 times.
135 for(int32_t i=0; i<guys.Count(); i++)
7483 {
7484
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 84 times.
114 if(((enemy*)guys.spr(i))->bgsfx)
7485 84 stop_sfx(((enemy*)guys.spr(i))->bgsfx);
7486 114 }
7487 }
7488 39585 }
7489
7490 261 void toggle_switches(dword flags, bool entry)
7491 {
7492
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 261 times.
261 if(!flags) return; //No flags to toggle
7493
7494 522 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7495 261 toggle_switches(flags, entry, create_screen_handles(scr));
7496 261 });
7497 261 }
7498 55201 void toggle_switches(dword flags, bool entry, const screen_handles_t& screen_handles)
7499 {
7500
2/2
✓ Branch 0 taken 931 times.
✓ Branch 1 taken 54270 times.
55201 if(!flags) return; //No flags to toggle
7501
7502 931 mapscr* m = screen_handles[0].base_scr;
7503 931 int screen = m->screen;
7504 931 bool is_active_screen = is_in_current_region(m);
7505
7506 525235 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
7507 524304 byte togglegrid[176] = {0};
7508 524304 mapscr* scr = rpos_handle.scr;
7509 524304 int lyr = rpos_handle.layer;
7510 524304 int pos = rpos_handle.pos;
7511 524304 newcombo const& cmb = combobuf[scr->data[pos]];
7512
2/2
✓ Branch 0 taken 39424 times.
✓ Branch 1 taken 484880 times.
524304 if(is_active_screen)
7513
1/2
✓ Branch 0 taken 484880 times.
✗ Branch 1 not taken.
641011 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7514
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 156131 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
156131 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7515 }, ctrigSWITCHSTATE);
7516
3/4
✓ Branch 0 taken 523592 times.
✓ Branch 1 taken 712 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2809 times.
524304 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32
7517
2/2
✓ Branch 0 taken 2809 times.
✓ Branch 1 taken 521495 times.
524304 && !(cmb.usrflags & cflag11)) //global state
7518 {
7519
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2363 times.
2809 if(flags&(1<<cmb.attribytes[0]))
7520 {
7521 2363 set<int32_t> oldData;
7522 //Increment the combo/cset by the attributes
7523 2363 int32_t cmbofs = (cmb.attributes[0]/10000L);
7524 2363 int32_t csofs = (cmb.attributes[1]/10000L);
7525
1/2
✓ Branch 0 taken 2363 times.
✗ Branch 1 not taken.
2363 oldData.insert(scr->data[pos]);
7526
1/2
✓ Branch 0 taken 2363 times.
✗ Branch 1 not taken.
2363 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7527 2363 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7528
4/4
✓ Branch 0 taken 1444 times.
✓ Branch 1 taken 919 times.
✓ Branch 2 taken 1206 times.
✓ Branch 3 taken 238 times.
2363 if(entry && (cmb.usrflags&cflag8))
7529 {
7530 238 newcombo const* tmp = &combobuf[scr->data[pos]];
7531
2/4
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
238 while(tmp->can_cycle())
7532 {
7533 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7534 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7535 if(oldData.find(cid) != oldData.end())
7536 break;
7537
7538 scr->data[pos] = cid;
7539 if(!(tmp->animflags & AF_CYCLENOCSET))
7540 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7541 oldData.insert(cid);
7542 tmp = &combobuf[cid];
7543 }
7544 238 }
7545 2363 int32_t cmbid = scr->data[pos];
7546
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2322 times.
2363 if(combobuf[cmbid].animflags & AF_CYCLE)
7547 {
7548 41 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7549 41 combobuf[cmbid].cur_frame=0;
7550 41 combobuf[cmbid].aclk = 0;
7551
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 combo_caches::drawing.refresh(cmbid);
7552 41 }
7553 2363 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7554
2/2
✓ Branch 0 taken 560 times.
✓ Branch 1 taken 1803 times.
2363 if(cmb.type == cCSWITCH) return; //Switches don't toggle other layers
7555
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2147 times.
2147 for(int32_t lyr2 = 0; lyr2 < 7; ++lyr2) //Toggle same pos on other layers, if flag set
7556 {
7557
2/2
✓ Branch 0 taken 1671 times.
✓ Branch 1 taken 476 times.
2147 if(lyr==lyr2) return;
7558
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 344 times.
476 if(!(cmb.usrflags&(1<<lyr2))) return;
7559
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(togglegrid[pos]&(1<<lyr2)) return;
7560
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
344 mapscr* scr_2 = (lyr2 ? get_scr_layer(screen, lyr2) : m);
7561
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(!scr_2->data[pos]) //Don't increment empty space
7562 return;
7563 344 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7564
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
344 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK) && !(cmb.usrflags & cflag11)
7565 && cmb_2.attribytes[0] < 32 && (flags&(1<<cmb_2.attribytes[0])))
7566 return; //This is a switch/block that will be hit later in the loop!
7567 344 set<int32_t> oldData2;
7568 //Increment the combo/cset by the original cmb's attributes
7569
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 oldData2.insert(scr_2->data[pos]);
7570
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7571 344 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7572
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
344 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7573 {
7574 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7575 while(tmp->can_cycle())
7576 {
7577 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7578 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7579 if(oldData2.find(cid) != oldData2.end())
7580 break;
7581
7582 scr_2->data[pos] = cid;
7583 if(!(tmp->animflags & AF_CYCLENOCSET))
7584 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7585 oldData2.insert(cid);
7586 tmp = &combobuf[cid];
7587 }
7588 }
7589 344 int32_t cmbid2 = scr_2->data[pos];
7590
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(combobuf[cmbid2].animflags & AF_CYCLE)
7591 {
7592 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7593 combobuf[cmbid2].cur_frame=0;
7594 combobuf[cmbid2].aclk = 0;
7595 combo_caches::drawing.refresh(cmbid2);
7596 }
7597 344 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7598 344 }
7599
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 2363 times.
✗ Branch 2 not taken.
2363 }
7600 446 }
7601 524304 });
7602
7603
3/4
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 412 times.
✓ Branch 2 taken 519 times.
✗ Branch 3 not taken.
931 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7604 {
7605 newcombo const& cmb = combobuf[mblock2.bcombo];
7606 if(!(cmb.usrflags & cflag11) && (cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32)
7607 {
7608 if(flags&(1<<cmb.attribytes[0]))
7609 {
7610 //Increment the combo/cset by the attributes
7611 int32_t cmbofs = (cmb.attributes[0]/10000L);
7612 int32_t csofs = (cmb.attributes[1]/10000L);
7613 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7614 mblock2.cs = (mblock2.cs + csofs) & 15;
7615 int32_t cmbid = mblock2.bcombo;
7616 if(combobuf[cmbid].animflags & AF_CYCLE)
7617 {
7618 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7619 combobuf[cmbid].cur_frame=0;
7620 combobuf[cmbid].aclk = 0;
7621 combo_caches::drawing.refresh(cmbid);
7622 }
7623 }
7624 }
7625 }
7626
7627
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 707 times.
931 if (is_active_screen)
7628 {
7629 707 int screen_index_offset = get_region_screen_offset(m->screen);
7630 707 word c = m->numFFC();
7631
2/2
✓ Branch 0 taken 565 times.
✓ Branch 1 taken 707 times.
1272 for (int q = 0; q < c; ++q)
7632 {
7633 565 auto ffc_handle = *m->getFFCHandle(q, screen_index_offset);
7634
1/2
✓ Branch 0 taken 565 times.
✗ Branch 1 not taken.
596 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7635
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
31 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7636 }, ctrigSWITCHSTATE);
7637 565 }
7638 707 }
7639 55201 }
7640
7641 1 void toggle_gswitches(int32_t state, bool entry)
7642 {
7643 2 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7644 1 toggle_gswitches(state, entry, create_screen_handles(scr));
7645 1 });
7646 1 }
7647 1 void toggle_gswitches(int32_t state, bool entry, const screen_handles_t& screen_handles)
7648 {
7649 1 bool states[256] = {false};
7650 1 states[state] = true;
7651 1 toggle_gswitches(states, entry, screen_handles);
7652 1 }
7653 15790575 void toggle_gswitches(bool* states, bool entry, const screen_handles_t& screen_handles)
7654 {
7655
1/2
✓ Branch 0 taken 15790575 times.
✗ Branch 1 not taken.
15790575 if(!states) return;
7656
7657 15790575 auto& combo_cache = combo_caches::gswitch;
7658 15790575 mapscr* base_scr = screen_handles[0].base_scr;
7659 15790575 int screen = base_scr->screen;
7660 15790575 bool is_active_screen = is_in_current_region(base_scr);
7661 15790575 byte togglegrid[176] = {0};
7662
2/2
✓ Branch 0 taken 15790575 times.
✓ Branch 1 taken 110534025 times.
126324600 for(int32_t lyr = 0; lyr <= 6; ++lyr)
7663 {
7664 110534025 mapscr* scr = screen_handles[lyr].scr;
7665
2/2
✓ Branch 0 taken 35893601 times.
✓ Branch 1 taken 74640424 times.
110534025 if (!scr)
7666 74640424 continue;
7667
7668
2/2
✓ Branch 0 taken 35893601 times.
✓ Branch 1 taken 6317273776 times.
6353167377 for(int32_t pos = 0; pos < 176; ++pos)
7669 {
7670 6317273776 int cid = scr->data[pos];
7671 6317273776 auto& mini_cmb = combo_cache.minis[cid];
7672
7673
2/2
✓ Branch 0 taken 2910336 times.
✓ Branch 1 taken 6314363440 times.
6317273776 if (is_active_screen)
7674 {
7675
2/2
✓ Branch 0 taken 6314361558 times.
✓ Branch 1 taken 1882 times.
6314363440 if (mini_cmb.trigger_global_state)
7676 {
7677 1882 auto rpos_handle = get_rpos_handle_for_screen(screen, lyr, pos);
7678
1/2
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
3764 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7679
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1882 times.
1882 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7680 }, ctrigSWITCHSTATE);
7681 1882 }
7682 6314363440 }
7683
7684
2/2
✓ Branch 0 taken 55356 times.
✓ Branch 1 taken 6317218420 times.
6317273776 if (!mini_cmb.has_global_state)
7685 6317218420 continue;
7686
7687 55356 newcombo const& cmb = combobuf[cid];
7688
2/4
✓ Branch 0 taken 55356 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 55356 times.
55356 if(cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK)
7689 {
7690 if(states[cmb.attribytes[0]])
7691 {
7692 set<int32_t> oldData;
7693 //Increment the combo/cset by the attributes
7694 int32_t cmbofs = (cmb.attributes[0]/10000L);
7695 int32_t csofs = (cmb.attributes[1]/10000L);
7696 oldData.insert(scr->data[pos]);
7697 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7698 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7699 if(entry && (cmb.usrflags&cflag8))
7700 {
7701 newcombo const* tmp = &combobuf[scr->data[pos]];
7702 while(tmp->can_cycle())
7703 {
7704 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7705 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7706 if(oldData.find(cid) != oldData.end())
7707 break;
7708 scr->data[pos] = cid;
7709 if(!(tmp->animflags & AF_CYCLENOCSET))
7710 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7711 oldData.insert(cid);
7712 tmp = &combobuf[cid];
7713 }
7714 }
7715 int32_t cmbid = scr->data[pos];
7716 if(combobuf[cmbid].animflags & AF_CYCLE)
7717 {
7718 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7719 combobuf[cmbid].cur_frame=0;
7720 combobuf[cmbid].aclk = 0;
7721 combo_caches::drawing.refresh(cmbid);
7722 }
7723 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7724 if(cmb.type == cCSWITCH) continue; //Switches don't toggle other layers
7725 for(int32_t lyr2 = 0; lyr2 <= 6; ++lyr2) //Toggle same pos on other layers, if flag set
7726 {
7727 if(lyr==lyr2) continue;
7728 if(!(cmb.usrflags&(1<<lyr2))) continue;
7729 if(togglegrid[pos]&(1<<lyr2)) continue;
7730 mapscr* scr_2 = lyr2 == 0 ? base_scr : get_scr_layer_valid(screen, lyr2);
7731 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7732 continue;
7733 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7734 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK)
7735 && (cmb_2.usrflags & cflag11) && (states[cmb_2.attribytes[0]]))
7736 continue; //This is a switch/block that will be hit later in the loop!
7737 set<int32_t> oldData2;
7738 //Increment the combo/cset by the original cmb's attributes
7739 oldData2.insert(scr_2->data[pos]);
7740 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7741 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7742 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7743 {
7744 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7745 while(tmp->can_cycle())
7746 {
7747 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7748 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7749 if(oldData2.find(cid) != oldData2.end())
7750 break;
7751 scr_2->data[pos] = cid;
7752 if(!(tmp->animflags & AF_CYCLENOCSET))
7753 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7754 oldData2.insert(cid);
7755 tmp = &combobuf[cid];
7756 }
7757 }
7758 int32_t cmbid2 = scr_2->data[pos];
7759 if(combobuf[cmbid2].animflags & AF_CYCLE)
7760 {
7761 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7762 combobuf[cmbid2].cur_frame=0;
7763 combobuf[cmbid2].aclk = 0;
7764 combo_caches::drawing.refresh(cmbid2);
7765 }
7766 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7767 }
7768 }
7769 }
7770 55356 }
7771 35893601 }
7772
7773
4/4
✓ Branch 0 taken 548400 times.
✓ Branch 1 taken 15242175 times.
✓ Branch 2 taken 543656 times.
✓ Branch 3 taken 4744 times.
15790575 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7774 {
7775 4744 newcombo const& cmb = combobuf[mblock2.bcombo];
7776
2/4
✓ Branch 0 taken 4744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4744 times.
✗ Branch 3 not taken.
4744 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && (cmb.usrflags & cflag11))
7777 {
7778 if(states[cmb.attribytes[0]])
7779 {
7780 //Increment the combo/cset by the attributes
7781 int32_t cmbofs = (cmb.attributes[0]/10000L);
7782 int32_t csofs = (cmb.attributes[1]/10000L);
7783 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7784 mblock2.cs = (mblock2.cs + csofs) & 15;
7785 int32_t cmbid = mblock2.bcombo;
7786 if(combobuf[cmbid].animflags & AF_CYCLE)
7787 {
7788 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7789 combobuf[cmbid].cur_frame=0;
7790 combobuf[cmbid].aclk = 0;
7791 combo_caches::drawing.refresh(cmbid);
7792 }
7793 }
7794 }
7795 4744 }
7796
7797
2/2
✓ Branch 0 taken 16159 times.
✓ Branch 1 taken 15774416 times.
15790575 if(is_active_screen)
7798 {
7799 15774416 int screen_index_offset = get_region_screen_offset(screen);
7800 15774416 word c = base_scr->numFFC();
7801
2/2
✓ Branch 0 taken 455562886 times.
✓ Branch 1 taken 15774416 times.
471337302 for (int q = 0; q < c; ++q)
7802 {
7803 455562886 auto ffc_handle = *base_scr->getFFCHandle(q, screen_index_offset);
7804
1/2
✓ Branch 0 taken 455562886 times.
✗ Branch 1 not taken.
455796224 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7805
1/2
✓ Branch 0 taken 233338 times.
✗ Branch 1 not taken.
233338 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7806 }, ctrigSWITCHSTATE);
7807 455562886 }
7808 15774416 }
7809 15790575 }
7810 54940 void toggle_gswitches_load(const screen_handles_t& screen_handles)
7811 {
7812 bool states[256];
7813
2/2
✓ Branch 0 taken 14064640 times.
✓ Branch 1 taken 54940 times.
14119580 for(auto q = 0; q < 256; ++q)
7814 {
7815 14064640 states[q] = game->gswitch_timers[q] != 0;
7816 14064640 }
7817 54940 toggle_gswitches(states, true, screen_handles);
7818 54940 }
7819 15346266 void run_gswitch_timers()
7820 {
7821 15346266 bool states[256] = {false};
7822 15346266 auto& m = game->gswitch_timers.mut_inner();
7823
2/2
✓ Branch 0 taken 3924601856 times.
✓ Branch 1 taken 15346266 times.
3939948122 for(auto it = m.begin(); it != m.end();)
7824 {
7825
2/2
✓ Branch 0 taken 3924601256 times.
✓ Branch 1 taken 600 times.
3924601856 if(it->second > 0)
7826
2/2
✓ Branch 0 taken 599 times.
✓ Branch 1 taken 1 times.
600 if(!--it->second)
7827 {
7828 1 states[it->first] = true;
7829 1 it = m.erase(it);
7830 1 continue;
7831 }
7832 3924601855 ++it;
7833 }
7834 31081900 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7835 15735634 toggle_gswitches(states, false, create_screen_handles(scr));
7836 15735634 });
7837 15346266 }
7838 1146 void onload_gswitch_timers() //Reset all timers that were counting down, no trigger necessary
7839 {
7840
2/2
✓ Branch 0 taken 293376 times.
✓ Branch 1 taken 1146 times.
294522 for(auto q = 0; q < 256; ++q)
7841 {
7842
1/2
✓ Branch 0 taken 293376 times.
✗ Branch 1 not taken.
293376 if(game->gswitch_timers[q] > 0)
7843 game->gswitch_timers[q] = 0;
7844 293376 }
7845 1146 }
7846
7847 /**** View Map ****/
7848
7849 int32_t mapres = 0;
7850 int32_t view_map_show_mode = 3;
7851
7852 129280 bool displayOnMap(int32_t x, int32_t y)
7853 {
7854 129280 int32_t s = (y<<4) + x;
7855 129280 int mi = mapind(cur_map, s);
7856
2/2
✓ Branch 0 taken 70863 times.
✓ Branch 1 taken 58417 times.
129280 if (!(game->maps[mi]&mVISITED))
7857 70863 return false;
7858
7859 // Don't display if not part of DMap
7860
4/4
✓ Branch 0 taken 15807 times.
✓ Branch 1 taken 42610 times.
✓ Branch 2 taken 4750 times.
✓ Branch 3 taken 4311 times.
67478 if(((DMaps[cur_dmap].flags&dmfDMAPMAP) &&
7861
1/2
✓ Branch 0 taken 15807 times.
✗ Branch 1 not taken.
15807 (DMaps[cur_dmap].type != dmOVERW) &&
7862
2/2
✓ Branch 0 taken 12631 times.
✓ Branch 1 taken 3176 times.
15807 !(x >= DMaps[cur_dmap].xoff &&
7863
2/2
✓ Branch 0 taken 9061 times.
✓ Branch 1 taken 3570 times.
12631 x < DMaps[cur_dmap].xoff+8 &&
7864 9061 DMaps[cur_dmap].grid[y]&(128>>(x-DMaps[cur_dmap].xoff)))))
7865 11057 return false;
7866 else
7867 47360 return true;
7868 129280 }
7869
7870 1010 void ViewMap()
7871 {
7872 1010 ViewingMap = true;
7873
7874 1010 BITMAP* mappic = NULL;
7875 static double scales[17] =
7876 {
7877 0.03125, 0.04419, 0.0625, 0.08839, 0.125, 0.177, 0.25, 0.3535,
7878 0.50, 0.707, 1.0, 1.414, 2.0, 2.828, 4.0, 5.657, 8.0
7879 };
7880
7881 // Cursor position for hero, in absolute map coordinates.
7882 1010 int32_t lx = ((cur_screen & 15) << 8) + HeroX() + 8;
7883 1010 int32_t ly = ((cur_screen >> 4) * 176) + HeroY() + 8;
7884
7885 int32_t px;
7886 int32_t py;
7887
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1010 times.
1010 if (is_in_scrolling_region())
7888 {
7889 // Center the player on the middle of the map view.
7890 px = (16*256/2 - lx) * 2;
7891 py = (8*176/2 - ly) * 2;
7892 }
7893 else
7894 {
7895 // Center the current screen on the middle of the map view.
7896 1010 px = ((8-(cur_screen&15)) << 9) - 256;
7897 1010 py = ((4-(cur_screen>>4)) * 352) - 176;
7898 }
7899
7900 1010 int32_t sc = 6;
7901
7902 1010 bool done=false, redraw=true;
7903
7904 1010 mappic = create_bitmap_ex(8,(256*16)>>mapres,(176*8)>>mapres);
7905
7906
1/2
✓ Branch 0 taken 1010 times.
✗ Branch 1 not taken.
1010 if(!mappic)
7907 {
7908 enter_sys_pal();
7909 jwin_alert("View Map","Not enough memory.",NULL,NULL,"OK",NULL,13,27,get_zc_font(font_lfont));
7910 exit_sys_pal();
7911 return;
7912 }
7913
7914 1010 clear_to_color(mappic, WHITE);
7915
7916 1010 auto prev_viewport = viewport;
7917 1010 viewport.x = 0;
7918 1010 viewport.y = 0;
7919
7920 // draw the map
7921 1010 BITMAP* screen_bmp = create_bitmap_ex(8, 256, 176);
7922 1010 combotile_add_x = 256;
7923 1010 combotile_add_y = 0;
7924 1010 bool classic_draw = get_qr(qr_CLASSIC_DRAWING_ORDER);
7925
2/2
✓ Branch 0 taken 8080 times.
✓ Branch 1 taken 1010 times.
9090 for(int32_t y=0; y<8; y++)
7926 {
7927
2/2
✓ Branch 0 taken 8080 times.
✓ Branch 1 taken 129280 times.
137360 for(int32_t x=0; x<16; x++)
7928 {
7929
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 81920 times.
129280 if (!displayOnMap(x, y))
7930 81920 continue;
7931
7932 47360 int screen = map_scr_xy_to_index(x, y);
7933 47360 auto scrs = loadscr2(screen);
7934 47360 mapscr* scr = &scrs[0];
7935
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if (!scr->is_valid())
7936 continue;
7937
7938 screen_handles_t screen_handles;
7939
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 331520 times.
378880 for (int i = 0; i <= 6; i++)
7940
3/4
✓ Branch 0 taken 331520 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114582 times.
✓ Branch 3 taken 216938 times.
331520 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
7941
7942 47360 int xx = 0;
7943 47360 int yy = -playing_field_offset;
7944
7945
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 if (!classic_draw)
7946 for (int layer = -7; layer <= -4; ++layer)
7947 do_ffc_layer(screen_bmp, layer, screen_handles[0], xx, yy);
7948
7949
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 if(classic_draw)
7950 {
7951
2/2
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 47313 times.
47360 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7952
1/2
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
47 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7953
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7954 47360 }
7955
7956
2/2
✓ Branch 0 taken 213 times.
✓ Branch 1 taken 47147 times.
47360 if(XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
7957
1/2
✓ Branch 0 taken 213 times.
✗ Branch 1 not taken.
213 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7958
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, -3, screen_handles[0], xx, yy);
7959
7960
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47360 times.
47360 if(!classic_draw)
7961 {
7962 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7963 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7964 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7965 do_ffc_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7966 }
7967
7968
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if(lenscheck(scr,0)) putscr(scr, screen_bmp, 0, 0);
7969
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 0, screen_handles[0], xx, yy);
7970
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[1], xx, yy);
7971
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 1, screen_handles[0], xx, yy);
7972
7973
2/2
✓ Branch 0 taken 47313 times.
✓ Branch 1 taken 47 times.
47360 if(!XOR((scr->flags7&fLAYER2BG), DMaps[cur_dmap].flags&dmfLAYER2BG))
7974 {
7975
1/2
✓ Branch 0 taken 47313 times.
✗ Branch 1 not taken.
47313 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7976
1/2
✓ Branch 0 taken 47313 times.
✗ Branch 1 not taken.
47313 do_ffc_layer(screen_bmp, 2, screen_handles[0], xx, yy);
7977 47313 }
7978
7979
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 putscrdoors(scr, screen_bmp, xx, yy);
7980
2/2
✓ Branch 0 taken 43358 times.
✓ Branch 1 taken 4002 times.
47360 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
7981 {
7982
1/2
✓ Branch 0 taken 43358 times.
✗ Branch 1 not taken.
43358 do_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7983
2/2
✓ Branch 0 taken 3462 times.
✓ Branch 1 taken 39896 times.
43358 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
7984 {
7985
1/2
✓ Branch 0 taken 3462 times.
✗ Branch 1 not taken.
3462 do_layer(screen_bmp,-2, screen_handles[1], xx, yy);
7986
1/2
✓ Branch 0 taken 3462 times.
✗ Branch 1 not taken.
3462 do_layer(screen_bmp,-2, screen_handles[2], xx, yy);
7987 3462 }
7988 43358 }
7989
7990
2/2
✓ Branch 0 taken 47147 times.
✓ Branch 1 taken 213 times.
47360 if(!XOR((scr->flags7&fLAYER3BG), DMaps[cur_dmap].flags&dmfLAYER3BG))
7991 {
7992
1/2
✓ Branch 0 taken 47147 times.
✗ Branch 1 not taken.
47147 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7993
1/2
✓ Branch 0 taken 47147 times.
✗ Branch 1 not taken.
47147 do_ffc_layer(screen_bmp, 3, screen_handles[0], xx, yy);
7994 47147 }
7995
7996
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[4], xx, yy);
7997
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 4, screen_handles[0], xx, yy);
7998
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7999
2/2
✓ Branch 0 taken 7464 times.
✓ Branch 1 taken 39896 times.
47360 if(get_qr(qr_OVERHEAD_COMBOS_L1_L2))
8000 {
8001
1/2
✓ Branch 0 taken 7464 times.
✗ Branch 1 not taken.
7464 do_layer(screen_bmp,-1, screen_handles[1], xx, yy);
8002
1/2
✓ Branch 0 taken 7464 times.
✗ Branch 1 not taken.
7464 do_layer(screen_bmp,-1, screen_handles[2], xx, yy);
8003 7464 }
8004
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[5], xx, yy);
8005
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 5, screen_handles[0], xx, yy);
8006
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1680 times.
✓ Branch 3 taken 45680 times.
47360 if(replay_version_check(40))
8007
1/2
✓ Branch 0 taken 1680 times.
✗ Branch 1 not taken.
1680 do_ffc_layer(screen_bmp, -1000, screen_handles[0], xx, yy);
8008
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[6], xx, yy);
8009
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 6, screen_handles[0], xx, yy);
8010
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 7, screen_handles[0], xx, yy);
8011
8012
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 stretch_blit(screen_bmp, mappic, 0, 0, 256, 176, x<<(8-mapres), (y*176)>>mapres, 256>>mapres, 176>>mapres);
8013
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
47360 }
8014 8080 }
8015
8016 1010 viewport = prev_viewport;
8017 1010 combotile_add_x = 0;
8018 1010 combotile_add_y = 0;
8019
8020 1010 destroy_bitmap(screen_bmp);
8021 1010 clear_keybuf();
8022 1010 pause_all_sfx();
8023
8024 // view it
8025 1010 int32_t delay = 0;
8026
8027 1010 do
8028 {
8029
2/2
✓ Branch 0 taken 189085 times.
✓ Branch 1 taken 29891 times.
218976 if (replay_version_check(0, 11))
8030 29891 load_control_state();
8031
8032 218976 int32_t step = int32_t(16.0/scales[sc]);
8033 218976 step = (step>>1) + (step&1);
8034 218976 bool r = cRbtn();
8035
8036
1/2
✓ Branch 0 taken 218976 times.
✗ Branch 1 not taken.
218976 if(cLbtn())
8037 {
8038 step <<= 2;
8039 delay = 0;
8040 }
8041
8042
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 218976 times.
218976 if(r)
8043 {
8044 if(rUp())
8045 {
8046 py+=step;
8047 redraw=true;
8048 }
8049
8050 if(rDown())
8051 {
8052 py-=step;
8053 redraw=true;
8054 }
8055
8056 if(rLeft())
8057 {
8058 px+=step;
8059 redraw=true;
8060 }
8061
8062 if(rRight())
8063 {
8064 px-=step;
8065 redraw=true;
8066 }
8067 }
8068 else
8069 {
8070
2/2
✓ Branch 0 taken 203528 times.
✓ Branch 1 taken 15448 times.
218976 if(Up())
8071 {
8072 15448 py+=step;
8073 15448 redraw=true;
8074 15448 }
8075
8076
2/2
✓ Branch 0 taken 203410 times.
✓ Branch 1 taken 15566 times.
218976 if(Down())
8077 {
8078 15566 py-=step;
8079 15566 redraw=true;
8080 15566 }
8081
8082
2/2
✓ Branch 0 taken 191540 times.
✓ Branch 1 taken 27436 times.
218976 if(Left())
8083 {
8084 27436 px+=step;
8085 27436 redraw=true;
8086 27436 }
8087
8088
2/2
✓ Branch 0 taken 192194 times.
✓ Branch 1 taken 26782 times.
218976 if(Right())
8089 {
8090 26782 px-=step;
8091 26782 redraw=true;
8092 26782 }
8093 }
8094
8095
2/2
✓ Branch 0 taken 22044 times.
✓ Branch 1 taken 196932 times.
218976 if(delay)
8096 22044 --delay;
8097 else
8098 {
8099 196932 bool a = cAbtn();
8100 196932 bool b = cBbtn();
8101
8102
3/4
✓ Branch 0 taken 1786 times.
✓ Branch 1 taken 195146 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1786 times.
196932 if(a && !b)
8103 {
8104
1/2
✓ Branch 0 taken 1786 times.
✗ Branch 1 not taken.
1786 sc=zc_min(sc+1,16);
8105 1786 delay=8;
8106 1786 redraw=true;
8107 1786 }
8108
8109
3/4
✓ Branch 0 taken 972 times.
✓ Branch 1 taken 195960 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 972 times.
196932 if(b && !a)
8110 {
8111
2/2
✓ Branch 0 taken 971 times.
✓ Branch 1 taken 1 times.
972 sc=zc_max(sc-1,0);
8112 972 delay=8;
8113 972 redraw=true;
8114 972 }
8115 }
8116
8117
2/2
✓ Branch 0 taken 218965 times.
✓ Branch 1 taken 11 times.
218976 if(rPbtn())
8118 11 --view_map_show_mode;
8119
8120 218976 px = vbound(px,-4096,4096);
8121 218976 py = vbound(py,-1408,1408);
8122
8123 218976 double scale = scales[sc];
8124
8125
2/2
✓ Branch 0 taken 75341 times.
✓ Branch 1 taken 143635 times.
218976 if(!redraw)
8126 {
8127 143635 blit(scrollbuf_old,framebuf,256,0,0,0,256,232);
8128 143635 }
8129 else
8130 {
8131 75341 clear_to_color(framebuf,BLACK);
8132 150682 stretch_blit(mappic,framebuf,0,0,mappic->w,mappic->h,
8133 75341 int32_t(256+(int64_t(px)-mappic->w)*scale)/2,int32_t(224+(int64_t(py)-mappic->h)*scale)/2,
8134 75341 int32_t(mappic->w*scale),int32_t(mappic->h*scale));
8135
8136 75341 blit(framebuf,scrollbuf_old,0,0,256,0,256,232);
8137 75341 redraw=false;
8138 }
8139
8140 218976 int32_t x = int32_t(256+(px-((2048-int64_t(lx))*2))*scale)/2;
8141 218976 int32_t y = int32_t(224+(py-((704-int64_t(ly))*2))*scale)/2;
8142
8143
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 211510 times.
218976 if(view_map_show_mode&1)
8144 {
8145 211510 line(framebuf,x-7,y-7,x+7,y+7,(frame&3)+252);
8146 211510 line(framebuf,x+7,y-7,x-7,y+7,(frame&3)+252);
8147 211510 }
8148
8149
3/4
✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 213376 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5600 times.
218976 if(view_map_show_mode&2 || r)
8150 213376 textprintf_ex(framebuf,font,224,216,WHITE,BLACK,"%1.2f",scale);
8151
8152
1/2
✓ Branch 0 taken 218976 times.
✗ Branch 1 not taken.
218976 if(r)
8153 {
8154 textprintf_ex(framebuf,font,0,208,WHITE,BLACK,"m: %d %d",px,py);
8155 textprintf_ex(framebuf,font,0,216,WHITE,BLACK,"x: %d %d",x,y);
8156 }
8157
8158 218976 advanceframe(false, false);
8159
2/2
✓ Branch 0 taken 29891 times.
✓ Branch 1 taken 189085 times.
218976 if (replay_version_check(11))
8160 189085 load_control_state();
8161
8162
2/2
✓ Branch 0 taken 217967 times.
✓ Branch 1 taken 1009 times.
218976 if (getInput(btnS, INPUT_PRESS | INPUT_IGNORE_DISABLE))
8163 1009 done = true;
8164
8165
2/2
✓ Branch 0 taken 217966 times.
✓ Branch 1 taken 1010 times.
437952 }
8166
2/2
✓ Branch 0 taken 1009 times.
✓ Branch 1 taken 217967 times.
218976 while(!done && !Quit);
8167
8168 1010 ViewingMap = false;
8169 1010 destroy_bitmap(mappic);
8170 1010 resume_all_sfx();
8171 1010 }
8172
8173 1112 int32_t onViewMap()
8174 {
8175
4/6
✓ Branch 0 taken 1112 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1112 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 1010 times.
1112 if(Playing && cur_screen<128 && DMaps[cur_dmap].flags&dmfVIEWMAP)
8176 {
8177 1010 clear_to_color(framebuf,BLACK);
8178 1010 textout_centre_ex(framebuf,font,"Drawing map...",128,108,WHITE,BLACK);
8179 1010 advanceframe(true);
8180 1010 ViewMap();
8181 1010 }
8182
8183 1112 return D_O_K;
8184 }
8185
8186 38934698 bool isGrassType(int32_t type)
8187 {
8188
2/2
✓ Branch 0 taken 38176585 times.
✓ Branch 1 taken 758113 times.
38934698 switch(type)
8189 {
8190 case cTALLGRASS:
8191 case cTALLGRASSNEXT:
8192 case cTALLGRASSTOUCHY:
8193 758113 return true;
8194 }
8195
8196 38176585 return false;
8197 38934698 }
8198
8199 25672 bool isFlowersType(int32_t type)
8200 {
8201
2/2
✓ Branch 0 taken 21332 times.
✓ Branch 1 taken 4340 times.
25672 switch(type)
8202 {
8203 case cFLOWERS:
8204 case cFLOWERSTOUCHY:
8205 4340 return true;
8206 }
8207
8208 21332 return false;
8209 25672 }
8210
8211 bool isGenericType(int32_t type)
8212 {
8213 switch(type)
8214 {
8215 case cTRIGGERGENERIC:
8216 return true;
8217 }
8218
8219 return false;
8220 }
8221
8222 30978 bool isBushType(int32_t type)
8223 {
8224
2/2
✓ Branch 0 taken 25672 times.
✓ Branch 1 taken 5306 times.
30978 switch(type)
8225 {
8226 case cBUSH:
8227 case cBUSHNEXT:
8228 case cBUSHTOUCHY:
8229 case cBUSHNEXTTOUCHY:
8230
8231 5306 return true;
8232 }
8233
8234 25672 return false;
8235 30978 }
8236
8237 bool isSlashType(int32_t type)
8238 {
8239 switch(type)
8240 {
8241 case cSLASH:
8242 case cSLASHITEM:
8243 case cSLASHTOUCHY:
8244 case cSLASHITEMTOUCHY:
8245 case cSLASHNEXT:
8246 case cSLASHNEXTITEM:
8247 case cSLASHNEXTTOUCHY:
8248 case cSLASHNEXTITEMTOUCHY:
8249 return true;
8250 }
8251
8252 return false;
8253 }
8254
8255 18151 bool isCuttableNextType(int32_t type)
8256 {
8257
2/2
✓ Branch 0 taken 9830 times.
✓ Branch 1 taken 8321 times.
18151 switch(type)
8258 {
8259 case cSLASHNEXT:
8260 case cSLASHNEXTITEM:
8261 case cTALLGRASSNEXT:
8262 case cBUSHNEXT:
8263 case cSLASHNEXTTOUCHY:
8264 case cSLASHNEXTITEMTOUCHY:
8265 case cBUSHNEXTTOUCHY:
8266 8321 return true;
8267 }
8268
8269 9830 return false;
8270 18151 }
8271
8272 20007 bool isTouchyType(int32_t type)
8273 {
8274
2/2
✓ Branch 0 taken 8508 times.
✓ Branch 1 taken 11499 times.
20007 switch(type)
8275 {
8276 case cSLASHTOUCHY:
8277 case cSLASHITEMTOUCHY:
8278 case cBUSHTOUCHY:
8279 case cFLOWERSTOUCHY:
8280 case cTALLGRASSTOUCHY:
8281 case cSLASHNEXTTOUCHY:
8282 case cSLASHNEXTITEMTOUCHY:
8283 case cBUSHNEXTTOUCHY:
8284 11499 return true;
8285 }
8286
8287 8508 return false;
8288 20007 }
8289
8290 38867500 bool isCuttableType(int32_t type)
8291 {
8292
2/2
✓ Branch 0 taken 38414469 times.
✓ Branch 1 taken 453031 times.
38867500 switch(type)
8293 {
8294 case cSLASH:
8295 case cSLASHITEM:
8296 case cBUSH:
8297 case cFLOWERS:
8298 case cTALLGRASS:
8299 case cTALLGRASSNEXT:
8300 case cSLASHNEXT:
8301 case cSLASHNEXTITEM:
8302 case cBUSHNEXT:
8303
8304 case cSLASHTOUCHY:
8305 case cSLASHITEMTOUCHY:
8306 case cBUSHTOUCHY:
8307 case cFLOWERSTOUCHY:
8308 case cTALLGRASSTOUCHY:
8309 case cSLASHNEXTTOUCHY:
8310 case cSLASHNEXTITEMTOUCHY:
8311 case cBUSHNEXTTOUCHY:
8312 453031 return true;
8313 }
8314
8315 38414469 return false;
8316 38867500 }
8317
8318 19783 bool isCuttableItemType(int32_t type)
8319 {
8320
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 19331 times.
19783 switch(type)
8321 {
8322 case cSLASHITEM:
8323 case cBUSH:
8324 case cFLOWERS:
8325 case cTALLGRASS:
8326 case cTALLGRASSNEXT:
8327 case cSLASHNEXTITEM:
8328 case cBUSHNEXT:
8329
8330 case cSLASHITEMTOUCHY:
8331 case cBUSHTOUCHY:
8332 case cFLOWERSTOUCHY:
8333 case cTALLGRASSTOUCHY:
8334 case cSLASHNEXTITEMTOUCHY:
8335 case cBUSHNEXTTOUCHY:
8336 19331 return true;
8337 }
8338
8339 452 return false;
8340 19783 }
8341
8342 69 bool is_push(mapscr* m, int32_t pos)
8343 {
8344
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if(is_push_flag(m->sflag[pos]))
8345 return true;
8346 69 newcombo const& cmb = combobuf[m->data[pos]];
8347
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if(is_push_flag(cmb.flag))
8348 return true;
8349
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 55 times.
69 if(cmb.type == cPUSHBLOCK)
8350 14 return true;
8351
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
55 if(cmb.type == cSWITCHHOOK && (cmb.usrflags&cflag7))
8352 return true; //Counts as 'pushblock' flag
8353 55 return false;
8354 69 }
8355
8356 424 static std::map<int, screen_state_t> screen_states;
8357
8358 37527 std::map<int, screen_state_t>& get_screen_states()
8359 {
8360 37527 return screen_states;
8361 }
8362
8363 45801810 screen_state_t& get_screen_state(int screen)
8364 {
8365 45801810 return screen_states[screen];
8366 }
8367
8368 605 void clear_screen_states()
8369 {
8370 605 screen_states.clear();
8371 605 }
8372
8373 1597 void screen_item_set_state(int screen, ScreenItemState state)
8374 {
8375 1597 get_screen_state(screen).item_state = state;
8376 1597 }
8377
8378 557162 void mark_visited(int screen)
8379 {
8380
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 556687 times.
557162 if (screen < 0x80)
8381 {
8382
2/2
✓ Branch 0 taken 96919 times.
✓ Branch 1 taken 459768 times.
556687 if(DMaps[cur_dmap].flags&dmfVIEWMAP)
8383 459768 game->maps[mapind(cur_map, screen)] |= mVISITED;
8384
8385 556687 markBmap(-1, screen);
8386 556687 }
8387 557162 }
8388